习题3.10 汉诺塔的非递归实现

借助堆栈以非递归(循环)方式求解汉诺塔的问题(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--]);
 }
 
  
  
  

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值