问题:将n个从上到下逐渐变大的圆盘从x柱,经过y柱,移动到z柱,一次只能移动一个圆盘,且小圆盘上不能放大圆盘。
理解:
采用递归的思想,将一个大问题化解为很多个相似的小问题。
在汉诺塔问题中,我们可以从这个大问题中抽取两个圆盘进行单独分析,总结出这两个圆盘的交换规律,然后通过递归的算法就可以扩展到所有圆盘。
从上到下排序,将第n个圆盘和第n-1个圆盘从x柱借助y柱移动到z柱子:
1、将第n-1个圆盘从x柱移动到y柱。
2、将第n个圆盘从x柱移动到z柱。
3、将第n-1个圆盘从y柱移动到z柱。
以上就是圆盘移动的思路,下面是递归的流程:
n个圆盘从大到小依次往上重叠,全部在x柱子上。
要将第n个圆盘从x柱移动到z柱,先得把第n-1个圆盘从x柱移动到y柱。
要将第n-1个圆盘从x柱移动到y柱,先得把第n-2个圆盘从x柱移动到z柱。
要将第n-2个圆盘从x柱移动到z柱,先得把第n-3个圆盘从x柱移动到y柱。
......
要将第2个圆盘从从x柱移动到z柱,先得把第1个圆盘从x柱移动到y柱。
思路清楚后接下来就是写代码啦:
#include<stdio.h>
int count=0;//定义一个全局变量,用于计数。
move(int n, int from, int to)//move函数,打印移动的方式,将第n个圆盘从from柱移动到to柱。
{
count++; //移动一次,count次数加1;
printf("step:%-2d 将第 %d 个圆盘从 %d柱 移动到 %d 柱\n", count, n, from, to);
//"%-2d"表示将十进制数字以两位数表示并且左对齐,不足部分用空格表示。
//"%2d"表示将十进制数字以两位数表示并且右边对齐,不足部分用空格表示。
}
void hanoi(int n, int x, int y, int z) //将第n个圆盘从x柱借助y柱移动到z柱,要明白x,y,z的含义
{
if(n==0) //当n=0,递归结束
return;
hanoi(n-1, x, z, y); //先将第n个圆盘从x柱借助z柱移动到y柱
move(n, x, z); //再将第n个圆盘从x柱移动到z柱
hanoi(n-1, y, x, z); //先将第n-1个圆盘从y柱借助x柱移动到z柱
}
int main()
{
int n=0, x=1, y=2, z=3;
printf("请输入需要移动的圆盘个数:");
scanf("%d", &n);
hanoi(n, x, y, z);
printf("一共需要移动%d步", count);
return 0;
}