递归与循环
两者关系
理论上,递归与循环是等价的,任何循环都可以重写为递归形式。很多递归也可以用循环来代替。不同的是,递归需要使用栈,而栈的大小是有限的,因此,递归的深度也会受到一定的限制。
注:
1.Java不支持为递归。
2.有些语言没有循环语句,只能使用递归。
循环改递归的方法
递归就是一个函数或方法直接或间接地调用自己,形成类似于循环的效果。
把循环改写为递归的关键是发现逻辑上的“相似性”,此外,一定不要忘记递归的“出口”(递归的结束条件)。如果没有“出口”,程序将无限递归下去,形成一个死循环。
相对于上一次的递归而言,递归在状态上一定会有所改变,它的改变主要体现在参数的改变上。
例如,打印从0到n的程序:
def f(n):
if n>=1:
f(n-1)
print(n,end=' ')
f(10)
此外,实践使用时,要设置合适的参数,例如:打印从begin到end:
def f(begin,end):
id begin>end: #基线条件
return
print(begin) #打印结果
f(begin+1,end) #递归执行
构造相似性的方法
当没有明显的相似性时,就需要构造相似性,不相似的原因可能是缺少参数。递归与数学上的递推公式很类似。
例如:
#求数组arr中从begin开始到结束的元素的和
def f(arr,begin):
#...
if begin==a.length:
return 0;
#程序主体
int x=f(arr,begin+1)
return x+arr[begin]
#...
递归比较两个字符串是否相同:
def f(str1,str2):
if len(str1)!=len(str2);
return False
if len(str1)==0:
return True
if str1[0]!=str2[0]:
return False
return f(str1[1:],str2[1:])
递归调用注意事项
(1)递归调用仅仅是被调函数恰为主调函数的一种情况
(2)每次调用的层次不同
(3)每次分配形参并非同一个变量
(4)返回的次序
(5)调用不是goto,调用完毕以后一定要返回原来状态,因此要记录原始状态,而goto往往不返回。
总之,任何循环都可以写成递归,但是使用递归时一定不要忘记“出口”。