在正式讲之前,想就这个问题说几点自己的心得:汉诺塔问题其实很简单,并不是大家所想的什么洪水猛兽,只需要大家克服内心的抗拒别被自己以为的难吓跑了

汉诺塔(Hanoi)

首先,关于汉诺塔问题的起源,有兴趣的话可以自行去百度印度某神庙的传说。接下来,直接步入正题

问题描述:

n个盘子,3根柱子:A,B,C。
初,A柱从上到下串好了由小到大的盘子。目标:把A柱上的盘子原样移动到C柱上,要求:过程中必须始终保持大盘在下,小盘在上。

汉诺塔问题java 汉诺塔问题python_递归

问题分析:

先取简单的n=1,2,3,4找找看有没有规律:
n=1,很简单,直接A–>C(A到C) 1步
n=2,第一个盘先A–>B,第二个盘再A–>C,最后第一个盘再B–>C 3步
n=3, 懒得码字就直接上图了

汉诺塔问题java 汉诺塔问题python_算法_02


一共7步

n=4时,大家自己动手去推一下过程,这里我先把结果说了,一共15步(一定要自己动手去推一下过程,只有这样当我讲下面的思路时,大家才会有很深的影响,觉得,哦,原来是这样啊,就说当时推的时候,感觉有点怪)

在这几个例子的推导过程中,我们可以看到他们都有一个共同点:
在中间的推导过程中,都会出现这样一幕:A柱上的前n-1个盘子竟很规矩地(由上至下,从小到大)又串在B柱上,然后,我们又将最后一个盘子从A柱移到C柱,这样之后,希望大家可以明白剩下的n-1个盘子就相当于是自由的了,即可以按以前的规矩,“自由地”在3根柱子上移动了(因为,只要C柱上最大的那个盘子的位置不动,对剩下的n-1个盘子的移动就没有任何影响),剩下的任务就是:把B柱上的n-1个盘子移到C柱上,这一过程不就跟先前从A柱上移n-1个盘子到B柱是一样的了,只不过是从B柱移到C柱上罢了。这里有一个东西在我们脑子里要突破一下:实际上,三个柱子是没有任何区别的,把盘子从A移到B和从B移到C其实是差不多的,只不过是选“谁是出发柱,谁是中间柱,谁是目标柱”罢了,这里由于题目的原因,我们把A-出发柱,B-中间柱,C-目标柱,抛开本题,出发柱,目标柱,中间柱的选取当然由你自己定咯
所以解题(编程)步骤就出来了:

  1. 把上面n-1个盘子由A借助C移到B(由n个盘的移动转变n-1个盘的移动,递归不就出来了)
  2. 把最后一个盘子由A移到C
  3. 再把那n-1个盘子由B借助A移到C

具体代码如下(Python)

def move(n,a,b,c):
    if n==1:
        print(a,'-->',c)

    else:
        move(n-1,a,c,b)
        print(a,'-->',c)
        move(n-1,b,a,c)

move(4,'A','B','C')

移动次数的规律

n=1 1步
n=2 3步
n=3 7步
n=4 15步

f(n)=2*f(n-1)+1 (递归公式)
由f(1)=1=2^1-1
由递归公式得:
f(2)=2^2-1
f(3)=2^3-1
f(4)=2^4-1
……
f(n)=2^n-1