递归的两个特点:
(1)调用自身
(2)结束条件
def fun1(x):
print(x)
fun(x-1)
def fun2(x):
if x>0:
print(x)
fun2(x+1)
·以上两个函数都不是递归的,因为没有结束条件,可能会出现无限递归,不会出现最终结果。
def fun3(x):
if x>0:
print(x)
fun3(x-1)
def fun4(x):
if x>0:
fun4(x-1)
print(x)
·以上两个函数都是递归的,调用自身,且有结束条件。
fun3(4)的运行结果为:4 3 2 1
fun4(4)的运行结果为:1 2 3 4
递归的典型案例:汉诺塔问题
问题描述:
将A柱上的圆盘全部移到C柱,且保证小圆盘只能在大圆盘的上边,应如何移动圆盘,n个圆盘需要移动几步?
问题分解:
(1)将最大圆盘以上的n-1个圆盘由A柱移动到B柱;
(2)将最大的圆盘(也是目前A柱上的唯一一个圆盘移到C柱上);
(3)将B柱上的n-1个圆盘移动到C柱。
步骤分析:
在解决问题的三步中,只有(2)是只需移动一个圆盘,一步就可以完成。而(1)和(3)都相当于比原始问题规模减一的子问题(原始问题n个圆盘,(1)(3)均为n-1个圆盘)。在解决(1)和(3)是也是同样的道理,直到每一步都是只移动一个圆盘。也就是通过不断调用自身,将原本复杂的问题,最终分解为一步就可以解决的子问题。
代码实现:
def hanoi(n,a,b,c):#n表示圆盘总数,a表示最初圆盘所在位置,c表示最终圆盘所在位置,b表示从a柱移到c 柱要经过b柱
if n>0:
def(n-1,a,c,b)#第(1)步的实现
print("moving from %s to %s"%(a,c)#第(2)步的实现
def(n-1,b,a,c)#第(3)步的实现
总结:
(1)汉诺塔问题移动次数的推导公式:h(x)=h(x-1)+1+h(x-1)=2h(x-1)+1;
(2)n个圆盘需要移动2**n-1次。
说明:
本篇博客只是作为个人的听课笔记使用。具体课程为b站上清华大学博士讲解的数据结构与算法,课程讲的非常详细易懂,有需要的可以移步观看。