加入收藏 | 设为首页 | 会员中心 | 我要投稿 安卓应用网 (https://www.0791zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

使用Python语言理解递归

发布时间:2020-05-25 03:32:27 所属栏目:Python 来源:互联网
导读:递归 一个函数在执行过程中一次或多次调用其本身便是递归,就像是俄罗斯套娃一样,一个娃娃里包含另一个娃娃。 递归其实是程序设计语言学习过程中很快就会接触到的东西,但有关递归的理解可能还会有一些遗漏,下面

<div class="markdown-here-wrapper" data-md-url="https://i.cnblogs.com/EditPosts.aspx?postid=10312119"&gt;
<h1 id="-" style="margin: 20px 0px 10px; padding: 0px; font-weight: bold; color: black; font-size: 24px; border-bottom: 2px solid #aaaaaa;">递归
<p style="margin: 0px 0px 1.2em !important; font-size: 16px; line-height: 1.75em; padding-right: 0.5em; padding-left: 0.5em;">一个函数在执行过程中一次或多次调用其本身便是递归,就像是俄罗斯套娃一样,一个娃娃里包含另一个娃娃。


<p style="margin: 0px 0px 1.2em !important; font-size: 16px; line-height: 1.75em; padding-right: 0.5em; padding-left: 0.5em;">递归其实是程序设计语言学习过程中很快就会接触到的东西,但有关递归的理解可能还会有一些遗漏,下面对此方面进行更加深入的理解


<h1 id="-" style="margin: 20px 0px 10px; padding: 0px; font-weight: bold; color: black; font-size: 24px; border-bottom: 2px solid #aaaaaa;">递归的分类
<p style="margin: 0px 0px 1.2em !important; font-size: 16px; line-height: 1.75em; padding-right: 0.5em; padding-left: 0.5em;">这里根据递归调用的数量分为线性递归、二路递归与多重递归


<h3 id="-" style="margin: 20px 0px 10px; padding: 0px; font-weight: bold; color: black; font-size: 20px; border-bottom: 1px solid #aaaaaa;">线性递归
<p style="margin: 0px 0px 1.2em !important; font-size: 16px; line-height: 1.75em; padding-right: 0.5em; padding-left: 0.5em;">如果一个递归调用最多开始一个其他递归调用,我们称之为线性递归。


<p style="margin: 0px 0px 1.2em !important; font-size: 16px; line-height: 1.75em; padding-right: 0.5em; padding-left: 0.5em;">例如:

<span class="hljs-keyword" style="color: #ebbbff;"&gt;if</span> low > high:
    <span class="hljs-keyword" style="color: #ebbbff;"&gt;return</span> <span class="hljs-keyword" style="color: #ebbbff;"&gt;False</span>
<span class="hljs-keyword" style="color: #ebbbff;"&gt;else</span>:
    mid = (low + high) // <span class="hljs-number" style="color: #ffc58f;"&gt;2</span>
    <span class="hljs-keyword" style="color: #ebbbff;"&gt;if</span> target == data[mid]:
        <span class="hljs-keyword" style="color: #ebbbff;"&gt;return</span> <span class="hljs-keyword" style="color: #ebbbff;"&gt;True</span>
    <span class="hljs-keyword" style="color: #ebbbff;"&gt;elif</span> target < data[mid]:
        <span class="hljs-keyword" style="color: #ebbbff;"&gt;return</span> binary_search(data,mid - <span class="hljs-number" style="color: #ffc58f;"&gt;1</span>)
    <span class="hljs-keyword" style="color: #ebbbff;"&gt;else</span>:
        <span class="hljs-keyword" style="color: #ebbbff;"&gt;return</span> binary_search(data,mid + <span class="hljs-number" style="color: #ffc58f;"&gt;1</span>,high)


<p style="margin: 0px 0px 1.2em !important; font-size: 16px; line-height: 1.75em; padding-right: 0.5em; padding-left: 0.5em;">虽然在代码中有两个binary_search,但他们是不同条件执行的,每次只能执行一次,所以是线性递归。


<h3 id="-" style="margin: 20px 0px 10px; padding: 0px; font-weight: bold; color: black; font-size: 20px; border-bottom: 1px solid #aaaaaa;">二路递归
<p style="margin: 0px 0px 1.2em !important; font-size: 16px; line-height: 1.75em; padding-right: 0.5em; padding-left: 0.5em;">如果一个递归调用可以开始两个其他递归调用,我们称之为二路递归


<p style="margin: 0px 0px 1.2em !important; font-size: 16px; line-height: 1.75em; padding-right: 0.5em; padding-left: 0.5em;">例如:

"""</span>

<span class="hljs-keyword" style="color: #ebbbff;"&gt;if</span> start >= stop:
    <span class="hljs-keyword" style="color: #ebbbff;"&gt;return</span> <span class="hljs-number" style="color: #ffc58f;"&gt;0</span>
<span class="hljs-keyword" style="color: #ebbbff;"&gt;elif</span> start == stop - <span class="hljs-number" style="color: #ffc58f;"&gt;1</span>:
    <span class="hljs-keyword" style="color: #ebbbff;"&gt;return</span> S[start]
<span class="hljs-keyword" style="color: #ebbbff;"&gt;else</span>:
    mid = (start + stop) // <span class="hljs-number" style="color: #ffc58f;"&gt;2</span>
    <span class="hljs-keyword" style="color: #ebbbff;"&gt;return</span> binary_sum(S,mid) + binary_sum(S,mid,stop)


<p style="margin: 0px 0px 1.2em !important; font-size: 16px; line-height: 1.75em; padding-right: 0.5em; padding-left: 0.5em;">这个递归每次执行都会调用两次该函数,所以说是二路递归,每次递归后,范围缩小一半,所以该递归的深度是1+logn


<h3 id="-" style="margin: 20px 0px 10px; padding: 0px; font-weight: bold; color: black; font-size: 20px; border-bottom: 1px solid #aaaaaa;">多重递归
<p style="margin: 0px 0px 1.2em !important; font-size: 16px; line-height: 1.75em; padding-right: 0.5em; padding-left: 0.5em;">如果一个递归调用可以开始三个或者更多其他递归调用,我们称之为多重递归


<p style="margin: 0px 0px 1.2em !important; font-size: 16px; line-height: 1.75em; padding-right: 0.5em; padding-left: 0.5em;">例如:

<span class="hljs-function" style="color: #bbdaff;"><span class="hljs-keyword" style="color: #ebbbff;">def <span class="hljs-title" style="color: #7285b7;">disk_usage<span class="hljs-params" style="color: #ffc58f;">(path):
<span class="hljs-string" style="color: #d1f1a9;">"""
计算一个文件系统的磁盘使用情况,

"""</span>

total = os.path.getsize(path)
<span class="hljs-keyword" style="color: #ebbbff;"&gt;if</span> os.path.isdir(path):
    <span class="hljs-keyword" style="color: #ebbbff;"&gt;for</span> filename <span class="hljs-keyword" style="color: #ebbbff;"&gt;in</span> os.listdir(path):
        childpath = os.path.join(path,filename)
        total += disk_usage(childpath)
print(<span class="hljs-string" style="color: #d1f1a9;"&gt;'{0:<7}'</span>.format(total),path)
<span class="hljs-keyword" style="color: #ebbbff;"&gt;return</span> total


<p style="margin: 0px 0px 1.2em !important; font-size: 16px; line-height: 1.75em; padding-right: 0.5em; padding-left: 0.5em;">os.path.getsize为获得标识的文件或者目录使用的即时磁盘空间大小。我理解的是如果该标识的是一个文件,那么就是获得该文件的大小,如果是一个文件夹的话,那就是获得该文件夹的大小,但不包括文件夹里边的内容,就像是一个盒子中放了很多物品,但这里只计算了盒子的重量,但没有计算物品的重量,也就是计算了一个空盒子。所以这个递归函数中的递归调用次数取决于这一层文件或文件夹的数量,所以是多重递归。


<h1 id="-" style="margin: 20px 0px 10px; padding: 0px; font-weight: bold; color: black; font-size: 24px; border-bottom: 2px solid #aaaaaa;">递归的不足
<p style="margin: 0px 0px 1.2em !important; font-size: 16px; line-height: 1.75em; padding-right: 0.5em; padding-left: 0.5em;">递归的不足显然就是时间与空间的消耗,具体可以参考<a href="https://www.cnblogs.com/sfencs-hcy/p/10171457.html"&gt;https://www.cnblogs.com/sfencs-hcy/p/10171457.html ,这篇文章中使用了缓存的方法减少了斐波那契数列的计算消耗,在这里我们使用另一种方式来改善那种坏的递归:

"""</span>

<span class="hljs-keyword" style="color: #ebbbff;"&gt;if</span> n <= <span class="hljs-number" style="color: #ffc58f;"&gt;1</span>:
    <span class="hljs-keyword" style="color: #ebbbff;"&gt;return</span> (n,<span class="hljs-number" style="color: #ffc58f;"&gt;0</span>)
<span class="hljs-keyword" style="color: #ebbbff;"&gt;else</span>:
    (a,b) = fibonacci(n - <span class="hljs-number" style="color: #ffc58f;"&gt;1</span>)
    <span class="hljs-keyword" style="color: #ebbbff;"&gt;return</span>(a + b,a)

(编辑:安卓应用网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读