问题描述:
在Hanoi这个地方有一个寺庙,这里有3根柱子和64个大小不同的金碟子。每个碟子有一个孔可以穿过。所有的碟子都放在第一个柱子上,
而且按照从上到下碟子的大小依次增大的顺序摆设
![](https://i-blog.csdnimg.cn/blog_migrate/78e60a57b1ca603bc852e2d85841a82b.jpeg)
现在,假定寺庙里的僧侣要移动这些碟子,将它们从最左边移动到最右边的柱子上。不过移动的规则如下:
1. 每次只能从一个柱子的最上面移动一个碟子到另外一个柱子上。
2. 不能将大碟子放到小碟子的上面。
按照前面这个规则,我们该怎么去移动这些碟子呢?假定单位时间内可以移动一片碟子,那么最终移动这些碟子到目的柱子需要多长的时间呢?
1. 每次只能从一个柱子的最上面移动一个碟子到另外一个柱子上。
2. 不能将大碟子放到小碟子的上面。
按照前面这个规则,我们该怎么去移动这些碟子呢?假定单位时间内可以移动一片碟子,那么最终移动这些碟子到目的柱子需要多长的时间呢?
问题分析:
假设有一个盘子,编号为1,将1 从A挪到C,共一步;
假设有两个盘子,依次编号(从上到下,下同)1、2,最少步骤:1 从A挪到B,2从A挪到C,最后将1 从B挪到C,共计三步;
假设有三个盘子,依次编号1、2、3,最少步骤:1 从A挪到C,2从A挪到B,1从C挪到B,3从A挪到C,1从B挪到A,2从B挪到C,1从A挪到C,共计七步;
....
从上边,我们可以看出,若要完成n阶汉诺塔,则最少要移动[2的n次方)-1]次,当然无关紧要,通过分析可以看出,hanoi塔在移动时第一步总是将除最底层的当然也是最大的圆盘(n圆盘)之外的所有的圆盘挪动到B塔(
以C塔为辅助塔)
,第二步则是将最大的圆盘挪动到C塔(A塔当作辅助塔),最后将剩下所有的圆盘挪动到C塔,那么就可以通过程序模拟这种过程,将整个塔看作两部分,第一部分1到n-1个圆盘,第二部分是第n个圆盘,那么逻辑上就三步,第一步要以B为主塔,C为辅塔,将1~n-1的圆
盘挪动到B塔;第二步将n圆盘做到C;最后以A塔当作辅助塔,将除n盘外所有圆盘挪动到C盘
代码:
//编译已通过
#include <iostream>
using namespace std;
void move(int n, char a,char b){
cout << "编号" << n << " " << a<<"-->"<< b<<endl;
}
void hanoi(int n,char x,char y,char z){
if(n >= 1){
hanoi(n-1,x,z,y);//将x上编号为1到n-1的圆盘移到y,z作辅助塔
move(n,x,z); //将编号为n的圆盘从x移到z
hanoi(n-1,y,x,z);//将y上编号为1到n-1的圆盘移到z,x作辅助塔
}
}
int main()
{
int num;
char x,y,z;
cin >> num >> x >> y >> z;
hanoi(num,x,y,z);
return 0;
}
代码分析:
以三个圆盘为例,塔标为A、B、C,
运行结果:
![](https://i-blog.csdnimg.cn/blog_migrate/809a0939bdfe37739867f3a121f280ea.png)
关于这个递归程序通过跟踪程序的方法来分析解读(1~24为程序运行步骤,层数为递归层数,第一层为最外层依次递增)
第一层 | 1 hanoi(3ABC) |
|
|
| 12 move(3AC) |
|
|
| 24END |
第二层 | 2 hanoi(2ACB) |
| 7 move(2AB) |
| 13 hanoi(2BAC) |
| 19 move(2BC) |
|
|
第三层 | 3 hanoi(1ABC) | 5 move(1AC) | 8 hanoi(1CBA) | 10hanoi(1CB) | 14 hanoi(1BCA) | 16 move(1BA) | 20 hanoi(1ABC) | 22 move(1AC) |
|
第四层 | 4 hanoi(0ACB) | 6 hanoi(0BAC) | 9hanoi(0CBA) | 11 hanoi(0ACB) | 15 hanoi(0BAC) | 17 hanoi(0CBA) | 21 hanoi(0ACB) | 23 hanoi(0BAC) |
|