笔者见过的汉诺塔有两种玩法,一种是只能 A柱->B柱->C柱 ,另一种是 A柱->B柱->C柱->A柱 ,本文研究的是塔层只能按照 A柱->B柱->C柱 的规律移动的汉诺塔游戏。
二、利用递归进行步骤分解
这里有一个有趣的故事:一个和尚想要移动64层汉诺塔,他就想,寺庙这么多和尚,我可以让另一个和尚移动上面的63层汉诺塔,我只移动最后的第64层汉诺塔,这件事不就很简单了吗;而被第一个和尚请求去移动63层汉诺塔的和尚也想,我可以让另一个和尚移动上面的62层汉诺塔,我只移动最后的第63层汉诺塔;第三个和尚也想。。。就这样,一个十分复杂的汉诺塔问题,就被分解成了一个个的移动一个盘子的问题,这就是递归的思想。
在上述游戏规则下,利用递归的思想,汉诺塔的问题可以分解为五个步骤:
(1)将n-1层汉诺塔从A借助B转到C;
(2)将第N层由A转到B;
(3)将n-1层汉诺塔从C借助B转到A;
(4)将第N层由B转到C;
(5)将n-1层汉诺塔从A借助B转到C。
void hanoi(int n,int one,int two,int three)//n:需要移动的塔的层数;从one借助two转到three。
{
void move(int x,int y);
if(n==1) //当需要移动当前递归的最后一层时,将A柱中该层转到B,然后从B再转到C
{
move(one,two);
move(two,three);
}
else
{
hanoi(n-1,one,two,three);//将n-1层汉诺塔从A借助B转到C,将第N层由A转到B;
move(one,two);
hanoi(n-1,three,two,one);//将n-1层汉诺塔从C借助B转到A,将第N层由B转到C;
move(two,three);
hanoi(n-1,one,two,three);//将n-1层汉诺塔从A借助B转到C,n层的汉诺塔移动任务结束。
}
}
移动一个盘子可以使用一个move函数实现:
void move(int x,int y) //从X柱中移动一个盘到Y柱
{
void show(int x,int y);
show(x,y);
total=total+1; //用于记录总步数
Sleep(500);
}
三、数据的结构
N层汉诺塔需要用到N个盘子,上一层盘子的长度应为下一层盘子的程度+2,此处使用一个N*3的数组对三个柱子中的盘子长度进行存储,实际上,此处使用栈会比使用固定大小数组会更方便也更节约内存。
| 0 | 0 | 4 |
| 0 | 0 | 6 |
| 0 | 0 | 8 |
上表就对应了上图的状态下的存储内容。
四、在命令行下的简易矩形笔者水平有限,现于命令行中使用空格和英文符号 "_"、"|" 进行矩形的绘制:
void rectangle(int *len,int n)
{
int x;
x=5+2*(n-1); //根据总层数得到柱子间距离的一半
printf("n");
for(int j=0;j<3;j++) //输出一行的盘子(矩形)的上边框
{
printf(" ");
for(int i=0;i
附 完整代码
#include
#include
#include
#include
int total=0;
int **data;
int total_layer;
int main()
{
void hanoi(int n,int one,int two,int three);
int m;
printf("Please input the number of diskes:");
scanf("%d",&m);
total_layer=m;
data=(int**)malloc(sizeof(int*)*m);
for(int i=0;i
参考文献
《C程序设计》(第五版)谭浩强 清华大学出版社



