汉诺塔(Tower of Hanoi )问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
基于Python的递归,实际上只用几行代码就可以打印出最少搬动盘子的步骤。
def move(n,a,b,c):
"""
# 注意这里的a,b,c是形参,与下面传入的实参'A','B','C'是通过位置对应,不是大小写字母对应
:param n: 盘子的个数
:param a: a柱子
:param b: b柱子
:param c: c柱子
:return:
"""
if n == 1:
print(a,"->",c)
else:
move(n-1,a,c,b) # 把(n-1)个盘子从a柱子经过c的辅助移到b
move(1,a,b,c)
move(n-1,b,a,c) # 把(n-1)个盘子从b柱子经过a的辅助移到c
move(3,'A','B','C') # 调用move函数并传实参
以 n = 3 为例,分析代码调用递归函数的流程:
需要明确的最关键的一点是:每一步的递归都要从算法的开头进行,直到出现输出为止。 也就是汉诺塔算法中每一次move都要回到开头再往下执行,直到n==1为止。
橙色箭头从上到下代表执行流程:
形参和实参的对应关系:这里形参全用小写字母表示,实参全用大写字母表示。
以打印步骤 (3) C —> B 为例,分析 move(1,C,A,B) 是怎么来的:
该步骤要执行 move(n-1,b,a,c) ,就要跳回 move(n,a,b,c) ,注意到形参 b,a,c 是在形参 a,b,c 的基础上把第二个位置的参数取出来放在第一个位置,
而 move(n-1,b,a,c) 的上一级 move(2,A,C,B) 的参数为 a = A, b = C, c = B; 所以我们把实参也做位置调整,把C取出来放到第一个位置,实参的顺序变为C,A,B,故形参与实参对应关系变为 a = C, b = A, c = B,所以有 move(1,C,A,B) 。
在计算机科学中,算法的时间复杂度是一个函数,它定量描述了该算法的运行时间。
求解方法一:
f(n) = 2f(n-1)+1
f(n)+1 = 2f(n-1)+2 = 2[f(n-1)+1] (1)
f(n-1)+1 = 2[f(n-2)+1] (2)
f(n-2)+1 = 2[f(n-3)+1] (3)
f(n-3)+1 = 2[f(n-4)+1] (4)
. .
. .
. .
f(2)+1 = 2[f(1)+1] (n-1)
将(2)式的左右两边同乘2^1,将(3)式的左右两边同乘2^2,将(4)式的左右两边同乘2^3,以此类推…将(n-1)式的左右两边同乘2^(n-2),最后将这(n-1)个式子全部相加,等号左边加左边,等号右边加右边,化简可得:
f(n)+2^0+2^1+2^2+...+2^(n-2) = 2^1+2^2+2^3+...+2^(n-1)+2^(n-1)
f(n) = 2^1+2^2+2^3+...+2^(n-2)+2*2^(n-1)-2^0-2^1-2^2-...-2^(n-2)
f(n) = 2*2^(n-1)-1
=> f(n) = 2^n - 1
求解方法二:
f(n) = 2f(n-1)+1
f(n)+1 = 2f(n-1)+2 = 2[f(n-1)+1]
设 f(n)+1 = Un,则2[f(n-1)+1] = 2U(n-1) 注:U后面的n与(n-1)均为下标,以下同理:
Un = 2U(n-1)
U(n-1) = 2U(n-2)
故:Un = 2U(n-1) = 2*2U(n-2) = 2*2*2U(n-3) = ...
=> Un = 2^1*U(n-1) = 2^2*U(n-2) = 2^3*U(n-3) = ... = 2^(n-1)*U1
又因为上面设 Un = f(n)+1,故:U1 = f(1)+1 = 2
所以:Un = 2^(n-1)*U1 = 2^(n-1)*2 = 2^n = f(n)+1
=> f(n) = 2^n - 1
由于时间复杂度都是考虑问题规模n非常大的情况,所以常数可以忽略不计,故汉诺塔问题的时间复杂度为:O(2^n)
根据递推公式:f(n) = 2f(n-1)+1 ,又f(1) = 1,可知:f(2) = 3, f(3) = 7, f(4) = 15, f(5) = 31,总结规律可得:f(n) = 2^n - 1,因此时间复杂度为:O(2^n)
==================================================================
本文使用示例小游戏为:
http://www.4399.com/flash/293.htm#search3