汉诺塔问题详解

1,317 阅读2分钟

汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着 64 片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。

题目:在 A,B,C 三根柱子上,有 n 个不同大小的圆盘,一开始他们都叠在 A 上 ,你的目标是在最少的合法移动步数内将所有盘子从 A 塔移动到 C 塔。 游戏中的每一步规则如下:

  1. 每一步只允许移动一个盘子(从一根柱子最上方到另一个柱子的最上方)
  2. 移动的过程中,你必须保证大的盘子不能在小的盘子上方(小的可以放在大的上面,最大盘子下面不能有任何其他大小的盘子)

解析:

(1) n == 1

第1次  1号盘  A---->C       sum = 1 次

      

(2) n == 2

第1次  1号盘  A---->B

第2次  2号盘  A---->C

第3次  1号盘  B---->C        sum = 3 次

(3)n == 3

第1次  1号盘  A---->C

第2次  2号盘  A---->B

第3次  1号盘  C---->B

第4次  3号盘  A---->C

第5次  1号盘  B---->A

第6次  2号盘  B---->C

第7次  1号盘  A---->C        sum = 7 次

...

由上面的三步再往下找规律可以发现,移动次数为:2^n - 1,并总结出三步规律如下:

1.把 A 上面的编号为 1 到 n-1 的所有盘子先由 A 移到 B
2.把 A 中仅剩的编号为 n 的盘子由 A 移动到 C
3.把 B 中的 n-1 个盘子由 B 移动到 C

上述步骤可以通过递归来实现:

def hanoi(n, a, b, c):
	if n==1:
	    print("%s --> %s"%(a, c))
	    return
	hanoi(n-1, a, c, b)
	print("%s --> %s"%(a, c))
	hanoi(n-1, b, a, c)