要求:
将A柱上的圆盘移动到B柱上,每次只能移动柱子最顶端的一个圆盘,并且小圆盘必须要在大圆盘上面。
分析:
上图提供了一个四个圆盘的情况,那么完成圆盘由A柱移动到B柱需要几步?为了大家更好得理解这个问题,我们从A柱上只有一个圆盘开始分析:
A柱起始圆盘个数 | 操作次数 | 等价表达式 | 移动顺序 |
1 | 1 | 2^1 - 1 | A1->B1 |
2 | 3 | 2^2 - 1 | A1->C1; A2->B2; C1->B1 |
3 | 7 | 2^3 - 1 | A1->B1; A2->C2; B1->C1; A3->B3; C1->A1; C2->B2; A1->B1 |
4 | 15 | 2^4 - 1 | …… |
规律:
有n个圆盘则最少需要操作2^n - 1次;
可以将n个圆盘的处理理解为将先将上面的n-1个圆盘按顺序移动到辅助柱C上,再将第n个圆盘移动到目标柱B上,然后将C上的n-1个圆盘移动到B上,也就是说将问题由n化简为n-1,n-1也同样可以化简为n-2……
从上面的规律总结中我们可以设计出一种递归算法:
#include <stdio.h>
void hanoi(int num, char sou, char tar, char aux)
{
static int i = 1;//统计移动次数
if (num == 1) //如果圆盘数量仅有 1 个,则直接从起始柱移动到目标柱
{
printf("第%d次:从 %c 移动至 %c\n", i, sou, tar);
i++;
}
else
{
//递归调用 hanoi() 函数,将 num-1 个圆盘从起始柱移动到辅助柱上
hanoi(num - 1, sou, aux, tar);
//将起始柱上剩余的最后一个大圆盘移动到目标柱上
printf("第%d次:从 %c 移动至 %c\n", i, sou, tar);
i++;
//递归调用 hanoi() 函数,将辅助柱上的 num-1 圆盘移动到目标柱上
hanoi(num - 1, aux, tar, sou);
}
}
int main()
{
int n = 0;
scanf("%d", &n);//输入起始柱圆盘个数
hanoi(n, 'A', 'B', 'C');//A、B、C分别表示起始柱、目标柱、辅助柱
return 0;
}