递归
在数学与计算机科学中,是指在函数的定义中使用函数自身的方法,绝大多数编程语言支持函数的自调用
递归的强大之处在于它允许用户用有限的语句描述无限的对象。
因此,在计算机科学中,递归可以被用来描述无限步的运算,尽管描述运算的程序是有限的。
递归的两个必要条件
1.要有递推关系
2.要有临界
下面是用递归实现阶乘的代码
def factorial(n):
"""
求阶乘
:param n:最大值
:return:阶乘
"""
if n is 1:
return n
else:
# 这里调用本身的函数
return n * factorial(n - 1)
print("1*2*3*4*...*100=%E" % factorial(100))
执行结果如下:
1*2*3*4*...*100=9.332622E+157
汉诺塔
汉诺塔算法介绍
其实算法非常简单,当盘子的个数为n时,移动的次数应等于2^n – 1(有兴趣的可以自己证明试试看)。后来一位美国学者发现一种出人意料的简单方法,只要轮流进行两步操作就可以了。首先把三根柱子按顺序排成品字型,把所有的圆盘按从大到小的顺序放在柱子A上,根据圆盘的数量确定柱子的排放顺序:
若n为偶数,按顺时针方向依次摆放 A B C;
若n为奇数,按顺时针方向依次摆放 A C B。
具体操作如下:
(1)按顺时针方向把圆盘1从现在的柱子移动到下一根柱子
当n为偶数时,若圆盘1在柱子A,A→B;若圆盘1在柱子B,则B→C;若圆盘1在柱子C,C→A
当n为奇数时,若圆盘1在柱子A,A→C;若圆盘1在柱子C,则C→B;若圆盘1在柱子B,B→A
(2)接着,把另外两根柱子上可以移动的圆盘移动到新的柱子上。
有一根柱子为空时,非空柱子上的圆盘移动到空柱子上,
两根柱子都非空时,移动较小的圆盘到另一根柱子上。
(3)反复进行(1)、(2)操作,最后就能按规定完成汉诺塔的移动。
所以结果非常简单,就是按照移动规则向一个方向移动金片:
如3阶汉诺塔的移动:A→C,A→B,C→B,A→C,B→A,B→C,A→C
以上只是在实际移动时得出的技巧,真正的算法不必如此复杂,大致思路如下:
首先,将A柱子上n-1个盘子通过C柱子移动到B柱子上(相当于从A到B的汉罗塔)
接着,将A柱子上第n个盘子直接移动到C柱子上
最后,将B柱子上n-1个盘子通过A移动到C柱子上(相当于从B到C的汉罗塔)
除了中间一步之外,其余两步都是汉诺塔的递归操作,如此层层深入,直到最后只剩一个盘子为止
Python实现代码如下:
# 定义全局变量count,用来记录移动次数
count = 0
def hanoi(n, a, b, c):
"""
# Python递归实现汉诺塔
:param n: A柱上圆盘的个数
:param a: A柱子
:param b: B柱子
:param c: C柱子
:return:
"""
global count
if n == 1:
count += 1
print('移动第', count, '次', a, '-->', c)
else:
# 1.把A柱上n-1个圆盘通过C柱移动到B柱上
hanoi(n - 1, a, c, b)
# 2.把A柱上最大的移动到C柱子上
hanoi(1, a, b, c)
# 3.把B柱子上n-1个圆盘通过A柱移动到C柱子上
hanoi(n - 1, b, a, c)
执行结果如下:
移动第 1 次 A --> C
移动第 2 次 A --> B
移动第 3 次 C --> B
移动第 4 次 A --> C
移动第 5 次 B --> A
移动第 6 次 B --> C
移动第 7 次 A --> C
以上内容部分参考如下博文修改整理
作者:风在人舟
出处:博客园
博文:python递归详解+汉诺塔小案例