汉诺塔(Tower of Hanoi)源于印度传说中,大梵天创造世界时造了三根金钢石柱子,其中一根柱子自底向上叠着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
伪算法(重点理解):
1 if( n>1 ){
2 先把A柱子上的前n-1个盘子从A借助C移到B//重点
3 将A柱子上的第n个盘子直接移到C//第n个就是最下面的一个
4 再将B柱子上的n-1个盘子从B借助A移到C//重点
5 }
三个盘情况:移动盘子次数为7
四个盘情况:移动盘子次数为15
假设有n片,移动次数是f(n).显然f(1)=1,f(2)=3,f(3)=7,且f(k+1)=2*f(k)+1。此后不难证明f(n)=2^n-1。
1 #include<stdio.h>
2
3 //函数的形参A、B、C不一定代表的是A、B、C柱子,递归传参的时候会变化!
4 void hanoit(int n,char A,char B,char C){
5 if(n==1){
6 //如果剩下一个盘子,直接将A柱子上的盘子从A移到C(直接从初始塔移动到目标塔)
7 printf("将编号为%d的盘子从%c柱子移到%c柱子",n,A,C);
8 }
9 else{
10 //否则,先将A柱子上的n-1个盘子从A借助C移到B(从初始塔移动到介质塔)
11 hanoit(n-1,A,C,B);//注意参数顺序:从A借助C移到B
12
13 printf("将编号为%d的盘子从%c柱子移到%c柱子",n,A,C);
14
15 //最后将B柱子上的n-1个盘子从B借助A移到C(从介质塔移动到目标塔)
16 hanoit(n-1,B,A,C);
17 }
18 }
19
20 int main(){
21 //三个柱子A、B、C,分别的作用是初始柱、介质柱、目标柱
22 char ch1 = 'A';
23 char ch2 = 'B';
24 char ch3 = 'C';
25
26 int n;
27
28 printf("移动盘子的个数:");//也是最后一个盘子的编号,顶部第一个盘子的编号是1
29 scanf("%d",&n);
30
31 hanoit(n,'A','B','C');
32
33
34 return 0;
35 }