P123 例6-6 借助堆栈模拟系统的运行时进栈、出栈过程,把汉诺塔问题的递归算法转换为非递归算法,并分析非递归算法的时间复杂度。
头文件:SeqStack.h
#include<stdio.h>
#define MaxStackSize 100
typedef struct
{
int retAddr;
int nPara;
char fromPegPara;
char toPegPara;
char auxPegPara;
}DataType;
typedef struct
{
DataType stack[MaxStackSize];
int top;
}SeqStack;
void StackInitiate(SeqStack *S)
{
S->top=0;
}
int StackNotEmpty(SeqStack S)
{
if(S.top<=0)
return 0;
else
return 1;
}
int StackPush(SeqStack *S,DataType x)
{
if(S->top>=MaxStackSize)
{
printf("堆栈已满无法插入!\n");
return 0;
}
else
{
S->stack[S->top]=x;
S->top++;
return 1;
}
}
int StackPop(SeqStack *S,DataType *d)
{
if(S->top<=0)
{
printf("堆栈已空无数据元素出栈!\n");
return 0;
}
else
{
S->top--;
*d=S->stack[S->top];
return 1;
}
}
int StackTop(SeqStack S,DataType *d)
{
if(S.top<=0)
{
printf("堆栈已空!\n");
return 0;
}
else
{
*d=S.stack[S.top-1];
return 1;
}
}
源文件:例6-6.c
#include<stdio.h>
#include"SeqStack.h"
void SimTowers(int n,char fromPeg,char toPeg,char auxPeg)
{
DataType currarea;
SeqStack s;
char temp;
int i;
StackInitiate(&s);
currarea.nPara=n;
currarea.fromPegPara=fromPeg;
currarea.toPegPara=toPeg;
currarea.auxPegPara=auxPeg;
currarea.retAddr=1;
StackPush(&s,currarea);
start:
if(currarea.nPara==1)
{
printf("%s %c %s %c","move disk 1 from peg",currarea.fromPegPara,"to peg",currarea.toPegPara);
i=currarea.retAddr;
StackPop(&s,&currarea);
switch(i)
{
case 1:goto label1;
case 2:goto label2;
case 3:goto label3;
}
}
StackPush(&s,currarea);
currarea.nPara--;
temp=currarea.auxPegPara;
currarea.auxPegPara=currarea.toPegPara;
currarea.toPegPara=temp;
currarea.retAddr=2;
goto start;
label2:
printf("\n%s %d %s %c %s %c\n","move disk",currarea.nPara,"from peg",currarea.fromPegPara,"to peg",currarea.toPegPara);
StackPush(&s,currarea);
currarea.nPara--;
temp=currarea.fromPegPara;
currarea.fromPegPara=currarea.auxPegPara;
currarea.auxPegPara=temp;
currarea.retAddr=3;
goto start;
label3:
i=currarea.retAddr;
StackPop(&s,&currarea);
switch(i)
{
case 1:goto label1;
case 2:goto label2;
case 3:goto label3;
}
label1:
return;
}
int main()
{
SimTowers(4,'A','C','B');
return 0;
}