借助堆栈以非递归(循环)方式求解汉诺塔的问题(n, a, b, c),即将N个盘子从起始柱(标记为“a”)通过借助柱(标记为“b”)移动到目标柱(标记为“c”),并保证每个移动符合汉诺塔问题的要求。
输入格式:
输入为一个正整数N,即起始柱上的盘数。
输出格式:
每个操作(移动)占一行,按柱1 -> 柱2的格式输出。
输入样例:
3
输出样例:
a -> c
a -> b
c -> b
a -> c
b -> a
b -> c
a -> c
分析:
把from上的n个盘子看成两部分,一部分为n-1,一部分为1,则移动时,先把n-1移到aux,把1移到to,然后再把剩下的n-1移到to,利用堆栈来实现。
注意:
因为堆栈是先进后出,因此第三步应该最先压进堆栈,然后压第二步,最后压第一步。
代码
#include <stdio.h>
typedef struct
{
int n;//盘子数
char from;//起始柱
char aux;//辅助柱
char to;//目标柱
}Hanoi;
void hanoi(int N,char from,char aux,char to)
{
Hanoi stack[200];
int top=-1;
stack[++top]={N,from,aux,to};//存入初始值
while(top!=-1)//栈不为空
{
Hanoi now=stack[top--];//取出栈顶元素
if(now.n==1)//盘子数为1时
{
printf("%c -> %c\n",now.from,now.to);
}
else
{
/*先将n-1个盘子从from挪到aux,再将from上的1个盘子挪到to上,最后把aux上的n-1个盘子挪到to上*/
//因为是堆栈,先进后出,因此需要倒着压进堆栈
stack[++top]={now.n-1,now.aux,now.from,now.to};//把aux上的n-1个盘子挪到to上
stack[++top]={1,now.from,now.aux,now.to};//将from上的1个盘子挪到to上
stack[++top]={now.n-1,now.from,now.to,now.aux};//将n-1个盘子从from挪到aux
}
}
}
int main()
{
int N;
scanf("%d",&N);
char from='a';
char aux='b';
char to='c';
hanoi(N,from,aux,to);
return 0;
}