Hanoi塔 棧與遞歸C編程實現
參考書 嚴蔚敏 數據結構
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
typedef int ElemType;
typedef int Status;
#define STACK_SIZE 10
#define STACK_INCREMENT 10
#define OK 1
#define ERROR -1
typedef struct{
ElemType *base;
ElemType *top;
int stacksize;
char tag;
}Stack;
Status InitStack(Stack &S,char tag)
{
S.base=(ElemType*)malloc(STACK_SIZE*sizeof(ElemType));
if (!S.base)
return ERROR;
S.top=S.base;
S.tag=tag;
S.stacksize=STACK_SIZE;
return OK;
}
Status Pop(Stack &S,ElemType &e)
{
if (S.base==S.top)//判斷是否非空
return ERROR;
S.top--;//棧頂元素降低
e=*S.top;//輸出
return OK;
}
Status Push(Stack &S,ElemType e)
{
if ((S.top-S.base)>=S.stacksize)//棧滿追加數據元素
{
S.base=(ElemType *)realloc(S.base,(S.stacksize+STACK_INCREMENT)*sizeof(ElemType));
//指針名=(數據類型*)realloc(要改變內存大小的指針名,新的大小)。//新的大小一定要大於原來的大小不然的話會導致數據丟失!
if (!S.base)
exit(ERROR);
S.top=S.base+S.stacksize;
S.stacksize+=STACK_INCREMENT;
}
*S.top=e;
S.top++;
return OK;
}
Status StackEmpty(Stack &S)
{
if (S.base==S.top)
return 1;
else
return 0;
}
int c=0;//全局變量記錄搬運次數
void Move(Stack &x,ElemType n,Stack &z)
{
Pop(x,n);
Push(z,n);
}
void hanoi(ElemType n,Stack &x,Stack &y,Stack &z)
{
printf("%d:Move disk %d from %c to %c\n",++c,n,x.tag,z.tag);
if (n==1)
Move(x,1,z);
else
{
hanoi(n-1,x,z,y);//將x上編號爲1至n-1的圓盤移到y,z作爲補助塔
Move(x,n,z);//將編號爲n的圓盤從x移到z
hanoi(n-1,y,x,z);//將y上編號爲1至n-1的圓盤移到z,x作爲補助塔
}
}
void main()
{
int n;
Stack x,y,z;
char tagx='x';//給棧打標籤
char tagy='y';//給棧打標籤
char tagz='z';//給棧打標籤
ElemType e;
InitStack(x,tagx);
InitStack(y,tagy);
InitStack(z,tagz);
printf("請輸入Hanoi塔的高度\n");
scanf("%d",&n);
hanoi(n,x,y,z);
printf("搬運結束,輸入羅漢塔Z:\n");
while(!StackEmpty(z))
{
Pop(z,e);
printf("%d\n",e);
}
getch();
}
輸入塔高3
輸出
請輸入Hanoi塔的高度
3
1:Move disk 3 from x to z
2:Move disk 2 from x to y
3:Move disk 1 from x to z
4:Move disk 1 from z to y
5:Move disk 2 from y to z
6:Move disk 1 from y to x
7:Move disk 1 from x to z
搬運結束,輸入羅漢塔Z:
1
2
3