python基础之递归函数

递归是指通过一个函数体内调用自身的方式进行的控制流程。Python 中也可以使用递归函数来实现某些算法。递归函数为一种解决问题的方法,将问题分解成更小的原问题并递归求解,直至得到基本情况下的解,然后将结果合并得到原问题的解。这篇文章将基于 Python 语言,详细介绍递归函数的基础知识以及一些重要的案例。

1. 递归函数的基本概念

递归函数是指在函数里调用自身函数的过程。在递归过程中,函数会不断重复调用自身,直到达到递归的结束条件。递归分为两种情况:递归函数和递推函数。递归函数指在函数体内直接或间接地调用自身的函数,如下面的阶乘函数:

def factorial(n):

if n == 0 or n == 1:

return 1

else:

return n * factorial(n-1)

这个函数可以计算任意一个正整数 n 的阶乘。根据上面函数的递归定义,factorial(n) 的计算如下:

- 当 n = 0 时,factorial(n) 的值为 1;

- 当 n = 1 时,factorial(n) 的值为 1;

- 当 n > 1 时,factorial(n) 的值为 n * factorial(n-1)。

递推函数指在函数体内调用自身和其他函数,根据前面的计算结果得到后面的计算结果,如下面的斐波那契数列函数:

def fibonacci(n):

if n == 0:

return 0

elif n == 1:

return 1

else:

return fibonacci(n-1) + fibonacci(n-2)

这个函数可以计算出第 n 个斐波那契数列的值。根据上面函数的递归定义,fibonacci(n) 的计算如下:

- 当 n = 0 时,fibonacci(n) 的值为 0;

- 当 n = 1 时,fibonacci(n) 的值为 1;

- 当 n > 1 时,fibonacci(n) 的值为 fibonacci(n-1) + fibonacci(n-2)。

2. 递归函数的优缺点

递归函数的优点:

- 实现简单,代码清晰易懂;

- 容易理解和维护;

- 可以解决一些复杂的问题。

递归函数的缺点:

- 递归调用需要消耗大量的系统资源,会导致栈空间溢出;

- 递归过深会导致程序的执行效率下降;

- 递归函数实现的算法不一定是最优的。

3. 递归函数的应用案例

递归函数可以应用于很多场景,例如树形结构的处理、数字集的排列和组合等等。下面就来看几个递归函数的应用案例。

3.1 求所有数字的幂集

给定一个数字集合,求出该数字集合的所有幂集,即由集合中元素任意组合而成的所有子集。例如,数字集合 {1, 2, 3} 的幂集为:{?,{1},{2},{3},{1, 2},{1, 3},{2, 3},{1, 2, 3}}。

def power_set(nums):

if not nums:

return [[]]

else:

res = []

for s in power_set(nums[1:]):

res += [s, s+[nums[0]]]

return res

通过观察上面的代码,我们可以发现:power_set(nums) 函数的返回值为 nums 的幂集。其实现原理为:先对 nums[1:] 求出子集 res,在对 res 中的每个集合 s,加上第一个元素 nums[0],再将这些结果加入到集合 res 中并返回。

3.2 阶梯爬楼问题

有一个 n 级的阶梯,在每次只能上 1 级或 2 级的情况下,求出一共有多少种走法。例如,阶梯为 3 级时,有 3 种走法:1,1,1;1,2;2,1。

def climb_stairs(n):

if n == 1:

return 1

elif n == 2:

return 2

else:

return climb_stairs(n-1) + climb_stairs(n-2)

通过对上面代码的分析,我们可以得出:climb_stairs(n) 函数的返回值为阶梯为 n 级时的走法总数。其实现原理为:在 n-1 级阶梯的基础上爬一级或在 n-2 级阶梯的基础上爬两级(前提是阶梯高度大于等于 2)。

3.3 汉诺塔问题

汉诺塔问题是古老的印度传说,是一个经典的递归问题。这个问题源于一个古老传说:在一座印度庙宇的圣塔里,有三根针,最初,圆盘都在第一根针上,大的在下,小的在上。传说中,神诺伯将 64 个圆盘移动到第三根针上,而且根据规定,圆盘每次只能从大到小地移动一个,且不能把大盘子放在小盘子上面,求解神诺伯移动圆盘的步骤。

def hanoi_tower(n, start, end, aux):

if n == 1:

print("Move disk 1 from", start, "to", end)

else:

hanoi_tower(n-1, start, aux, end)

print("Move disk", n, "from", start, "to", end)

hanoi_tower(n-1, aux, end, start)

通过对上面代码的分析,我们可以得出:hanoi_tower(n, start, end, aux) 函数为汉诺塔问题的解法。其实现原理为:通过始棍、辅助棍和目标棍,反复地对较大的圆盘和较小的圆盘进行移动,直到达到移动指定数目的圆盘的目标。

4. 总结

在 Python 中,递归函数是一种解决问题的方法,可以将问题分解成更小的原问题,并通过不断递归求解达到最终的解决方案。递归函数既有优点,也有缺点,需要合理使用和优化。递归函数可以应用于很多场景,例如阶乘、斐波那契数列、幂集、阶梯爬楼和汉诺塔等等。最后,建议在使用递归函数时,要注意函数的返回值和终止条件,以免陷入死循环等问题。

后端开发标签