借助堆栈以非递归(循环)方式求解汉诺塔的问题(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
#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 100
typedef enum{
false,true
} bool;
typedef struct{
int N;
char A;//起始柱
char B;//借助柱
char C;//目标柱
} ElementType;//汉诺塔结构类型
//堆栈定义
typedef int Position;
typedef struct SNode *PtrToSNode;
struct SNode{
ElementType *Data;
Position Top;
int MaxSize;
};
typedef PtrToSNode Stack;
Stack createStack(int MaxSize);
bool isEmpty(Stack s);
void push(Stack s,ElementType X);
ElementType pop(Stack s);
void Hanoi(int n)
{
Stack s;
ElementType p,toPush;
s=createStack(MAXSIZE);
p.N=n;p.A='a';p.B='b';p.C='c';
push(s,p);
while(!isEmpty(s)){//堆栈不为空时
p=pop(s);
if(p.N==1)
printf("%c -> %c\n",p.A,p.C);
else{
toPush.N=p.N-1;
toPush.A=p.B;toPush.B=p.A;toPush.C=p.C;
push(s,toPush);//将第二个待解子问题(n-1,b,a,c)入栈
toPush.N=1;
toPush.A=p.A;toPush.B=p.B;toPush.C=p.C;
push(s,toPush) ;//将直接可求解的子问题(1,a,b,c)入栈
toPush.N=p.N-1;
toPush.A=p.A;toPush.B=p.C;toPush.C=p.B;
push(s,toPush);//将第一个待解子问题(n-1,a,c,b)入栈
}
}
}
int main(){
int n;
scanf("%d",&n);
Hanoi(n);
return 0;
}
//堆栈实现
Stack createStack(int MaxSize)
{
Stack s=(PtrToSNode)malloc(sizeof(struct SNode)) ;
s->Data=(ElementType *)malloc(MaxSize*sizeof(ElementType));
s->Top=-1;
s->MaxSize=MaxSize;
return s;
}
bool isEmpty(Stack s)
{
return (s->Top==-1);
}
void push(Stack s,ElementType x)
{
//简版入栈,不担心栈满的情况
s->Data[++s->Top]=x;
}
ElementType pop(Stack s)
{
//简版出栈,不担心栈空
return(s->Data[s->Top--]);
}