一.问题描述:
1)汉诺塔:有a、b、c三根杆,要求把a杆上的金盘全部移到c杆上,并仍保持原有顺序叠好。操作规则:每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下,小盘在上。
2)(n, a, b, c):将N个盘子从起始柱(标记为“a”)通过借助柱(标记为“b”)移动到目标柱(标记为“c”)
3)例:
二.思路
问题转换为:(n-1,a,c,b)(1,a,b,c)(n-1,b,a,c)
最开始,共n个盘在a柱上,先要移走(n-1)个盘。(因为最大的那个盘要在最下面,所以最大的盘直接移到c柱,那么(n-1)个盘只能移到b柱) (n-1,a,c,b)(1,a,b,c)
最后,要将b柱上的(n-1)个盘移动到c柱上。
三.具体实现
1.利用堆栈,先解决的问题后放入,压入顺序为:(n-1,b,a,c)(1,a,b,c)(n-1,a,c,b)
再不断将栈顶的问题分解
2.类型定义????????????
1)*Data前为struct:Data数组中的一个元素 包含 ElementType整体内所有元素
2)*Data前为enum????????
四.顺序堆栈的基本操作 (链式堆栈见数据结构书77)
1)顺序堆栈定义与创建:
注意:Stack S是对这个结构体整体的malloc申请
S->Data是对Data数组的申请
2)判断空、满:
3.入栈
注意:S->Data [ ++(S->Top ) ] = X;
4.出栈
四.代码
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAXSIZE 111
typedef struct {
int N;
char A;
char B;
char C;
}ElementType; //汉诺塔问题结构类型
typedef struct LNode *PtrToLNode;
struct LNode{
ElementType *Data;
int Top;
int MaxSize;
};
typedef PtrToLNode Stack;
Stack CreateStack(int MaxSize);
bool IsFull(Stack S);
bool IsEmpty(Stack S);
ElementType Pop(Stack S);
void Push(Stack S,ElementType X);
void Hanoi(int N)
{
int flag=1;
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((flag==1)&&(P.N==1)){
printf("%c -> %c",P.A ,P.C );
flag=0;
}
else if((flag==0)&&(P.N==1)){
printf("\n%c -> %c",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);
toPush.N =1;
toPush.A =P.A ;
toPush.B =P.B ;
toPush.C =P.C ;
Push(S,toPush);
toPush.N =P.N -1;
toPush.A =P.A ;
toPush.B =P.C ;
toPush.C =P.B ;
Push(S,toPush);
}
}
}
Stack CreateStack(int MaxSize)
{
Stack S = (Stack)malloc(sizeof(struct LNode));
S->Data = (ElementType *)malloc(MaxSize*sizeof(ElementType));
S->Top =-1;
S->MaxSize = MaxSize;
return S;
}
void Push(Stack S,ElementType X) //X为需要压入的元素
{
if(IsFull(S)){
printf("堆栈满");
}
else{
S->Data[++(S->Top )] = X;
}
}
bool IsFull(Stack S)
{
return(S->Top == S->MaxSize-1);
}
bool IsEmpty(Stack S)
{
return(S->Top ==-1);
}
ElementType Pop(Stack S)
{
if(IsEmpty(S)){
printf("堆栈空");
return ;
}
else return(S->Data[(S->Top)--]);
}
int main()
{
int N;
scanf("%d",&N);
Hanoi(N);
return 0;
}