笔记
递归(recursion)
片面来说:函数不断调用自身,并且最终达到某个条件而停止,这是递归的一种体现。
Python3出于保护的目的,避免递归陷入死循环,默认的递归深度是100次,可以通过以下代码设置递归深度:
此时,函数recursion的递归深度被设置为了100w次。
递归与迭代的区别
递归(recursion):递归常被用来描述以自相似方法重复事物的过程,在数学和计算机科学中,指的是在函数定义中使用函数自身的方法。(A调用A)
迭代(iteration):重复反馈过程的活动,每一次迭代的结果会作为下一次迭代的初始值。(A重复调用B)
递归是一个树结构,从字面可以其理解为重复“递推”和“回归”的过程,当“递推”到达底部时就会开始“回归”,其过程相当于树的深度优先遍历。
迭代是一个环结构,从初始状态开始,每次迭代都遍历这个环,并更新状态,多次迭代直到到达结束状态。
理论上递归和迭代时间复杂度方面是一样的,但实际应用中(函数调用和函数调用堆栈的开销)递归比迭代效率要低。
来源:https://www.jianshu.com/p/32bcc45efd32
个人理解:
递归是由最终要求的结果一步步回推到最开始最简单的情况,而最开始最简单的情况的答案是已知的。
迭代是从最开始的情况开始,不断重复某一运算过程从而计算出最终要求的结果。
课后作业
测试题:
0. 递归在编程上的形式是如何表现的呢?
答:在函数的定义中,调用函数自身。
1. 递归必须满足哪两个基本条件?
答:1、可以通过递归调用来缩小问题规模,且新问题与原问题有着相同的形式。
2、存在一种简单情境,可以使递归在简单情境下退出。
即满足分治思想。
2. 思考一下,按照递归的特性,在编程中有没有不得不使用递归的情况?
答:当简单情境过多的时候。
标准答案:汉诺塔,目录索引(因为你永远不知道这个目录里边是否还有目录),快速排序(二十世纪十大算法之一),树结构的定义等如果使用递归,会事半功倍
3. 用递归去计算阶乘问题或斐波那契数列是很糟糕的算法,你知道为什么吗?
答:因为递归要不断开辟新的内存,资源利用率低。这两个问题一旦去计算的数字比较大,很容易超出递归的层数限制。
另外,如果递归一旦忘记了返回,或者错误的设置了返回条件,那么执行这样的递归代码就会变成一个无底洞:只进不出。
4. 请聊一聊递归的优缺点(无需官方陈词,想到什么写什么就可以)
答:优点:使代码看着简洁工整有条理,且一旦求解出具体问题的函数递归式,用递归的思想来编程就比较好理解(比如汉诺塔 难题)。
缺点:递归要不断开辟新的内存,资源利用率低。一旦计算的数字比较大,很容易超出递归的层数限制。
动动手:
0. 使用递归编写一个 power() 函数模拟内建函数 pow(),即 power(x, y) 为计算并返回 x 的 y 次幂的值。
答:
def power(x,y):
if y == 1:
return x
else:
y -= 1
return x*power(x,y)
1. 使用递归编写一个函数,利用欧几里得算法求最大公约数,例如 gcd(x, y) 返回值为参数 x 和参数 y 的最大公约数。
答:
def gcd(x,y):
if x%y == 0:
return y
else:
x,y = y,x%y
return gcd(x,y)