汉诺塔递归算法

来源:互联网 发布:秋之风腊肠淘宝 编辑:程序博客网 时间:2024/06/08 18:40

相信很多人都玩过汉诺塔游戏,今天来讨论下这个游戏的最优解的程序实现。
假设有A、B、C三根柱子,A是起始柱,B是目标柱,C是中转柱。

我们先来分析只有一层汉诺塔的情况,这个比较简单,只需要将A上面的块放到B上面就行了。

接下来分析两层汉诺塔的情况,总共分三步,首先将上面的一块放到C,然后将下面那块大的放到B,接着将C柱上面的那块放到B上面。

依次逻辑类推,我们假设N层的汉诺塔,那么大致也是分为三个步骤,
1.就是将上面的N-1块放到中转柱C。这个怎么移呢,就是将B作为中转站,将C作为目标站,层数是N-1层

2.然后将A的最后一块放到目标柱B上面

3.接着将C上面的N-1块移到目标柱B上面。这时是将C当作起始柱,A当作中转柱,B还是目标柱,层数是N-1层,这样就能将C的N-1块移到B上去。

这个利用到递归的思想,先申明函数
hannuo(int n, char x, char y, char z) //n是层数 x是起始柱 y是目标柱 z是中转柱
那么这三个步骤可以用用函数表示为

hannuo(n, x, y, z){         hannuo(n-1, x, z, y);       //参见红字 步骤一         Printf(“%c -> %c”, x, y);   //将A的最后一块放到 B    步骤二         Hannuo(n-1,z, y, x);       //参见红字 步骤三}

这个函数还不够完善,需要递归的初始条件完整代码如下

hannuo(n, x, y, z){         if(n== 0)         {                  //啥都不做         }         else        {                  hannuo(n-1, x, z, y);       //参见红字 步骤一                  Printf(“%c -> %c”, x, y);   //将A的最后一块放到 B    步骤二                  Hannuo(n-1,z, y, x);       //参见红字 步骤三        }}int main(void){         Hannuo(5,’A’, ‘B’, ‘C’);         Return0;}

分析这个代码,这个代码的精髓,或者说难点,就在于中间的printf,它的表征意义就是将起始到目的的这一过程给打印出来,思想是利用递归,分成最原始的一小份一小份来打印。

同时我们也可以分析步骤的数量
一层是1
二层是3
以上是我们手动分析的,
然后是我们的N层,他等于N-1层的步骤数+ 一个步骤+ N-1层的步骤数
Num(n) = 2 * num(n-1) + 1
Num(1) = 1
这个可以利用高中知识来解决,亦或者通过前几项发现规律,找到公式,然后在利用归纳法验证公式的正确性即可。

原创粉丝点击