关于汉诺塔Hanoi的计算公式理解及其递归代码


  • 什么是汉诺塔?

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

----以上来自百度百科

  • 汉诺塔移动次数计算公式

  移动次数计算公式为f(n)=2f(n-1)+1

这是一个递归的计算方式,可以靠想象理解一下:

i. 有3个柱子可以放,所有盘子在起始柱,还有一个目的柱和缓冲柱。在将起始柱的最大的一个盘,也就是目的柱接受的第一个盘之时。你的柱子情况应该是:起始柱子有一个盘子,目的柱子为空,缓冲柱子为(n-1)个盘子。

 

    起始柱            缓冲柱        目的柱

ii. 这时的盘子放置是一定的,因为你必须将(n-1)个盘子放在缓冲柱子,这也就是说你完成了f(n-1)次搬动,实现从起始柱子到缓冲柱子。

iii. 这时你再将起始柱的最大的盘子放到目的柱。也就是1次。

 

    起始柱            缓冲柱        目的柱

 

 iv. 这时再将缓冲柱子的(n-1)盘子盼到目的柱,(注:此时起始柱子可以用做缓冲柱子)。所以需要f(n-1)次搬运。

总结: 需要 f(n-1)+1+f(n-1)=2f(n-1)+1次搬运

用上面的公式,罗列f(1),f(2),f(3)可以得到f(n)=(2^n)-1

 

 

  • 代码

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 
 4 static int count = 0 ;
 5 void move(char getone,char putone){
 6         count ++;
 7         printf("%c-->%c\n", getone, putone);
 8 }
 9 void hanoit(int n, char a, char b, char c){   //这里的理解是a是起始柱,c是目的柱,b是缓冲
10         if(n == 1){
11                 move(a, c);
12         }
13         else{
14                 hanoit(n - 1, a, c, b);      //在运输除最大盘其余盘子时,将缓冲柱子作为目的柱子放置其余的(n-1)个柱
15                 printf("count :%d\n",count);
16                 move(a, c);                  //清掉(n-1)后剩下最大的,那么自然是从起始柱a放到目的柱c
17                 hanoit(n - 1, b, a, c);      //此时,剩下的(n-1)盘子时,缓冲柱b就变成起始柱了,目的柱c不变。
18         }
19 }
20 
21 int main(){int m;
22         scanf("%d", &m);
23         hanoit(m, 'A', 'B', 'C');
24         printf("count :%d\n",count);
25 
26         return 0;
27 }

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM