数据结构_习题3.10 汉诺塔的非递归实现(非 主流解法)
- 题目地址
- 题目分析:
- 本题目需要一定汉诺塔的前置知识,这里不提供;
- 分析递归代码
void hanoi(int k,char a,char b,char c) { if(k==1) printf("%c ->%c",a,c);//1 else { hanoi(k-1,a,c,b);//2 printf("%c ->%c",a,c);//3 hanoi(k-1,b,a,c);//3 }//4 }
此处1 2 3 4与上述递归代码注释1 2 3 4等价,那我们用一个栈记录数据和状态即可。
- 具体实现
#include<stdio.h> #include<stdlib.h> typedef struct funState{ int k;//待处理数量 char a,b,c;//a是起始柱,b是辅助,c是目标柱子 int tag;//见状态分析 }fs; typedef fs *fsp; int i=-1;//每个i指向存数据的位置,-1为空栈 fsp stk[16];//栈的初始化 void pushFsp(int k,char a,char b,char c){ stk[++i]=(fsp)malloc(sizeof(fsp));//栈顶上移 stk[i]->k=k;//待处理数量 stk[i]->a=a,stk[i]->b=b,stk[i]->c=c;//迁跃情况 stk[i]->tag=(k==1?1:2);//所进入的状态 } void popFsp(){ free(&stk[i]);//注意释放栈空间 i--;//出掉当前栈顶 if(i!=-1) stk[i]->tag++;//新栈顶的状态改变 } int main() { int n; scanf("%d",&n); pushFsp(n,'a','b','c'); while (i>=0) { if(stk[i]->tag==1)//出口:出到3或4 { printf("%c -> %c\n",stk[i]->a,stk[i]->c); popFsp(); } else if(stk[i]->tag==2)//入口:入到1或2 { pushFsp(stk[i]->k-1,stk[i]->a,stk[i]->c,stk[i]->b); } else if(stk[i]->tag==3)//入口:入到1或2 { printf("%c -> %c\n",stk[i]->a,stk[i]->c); pushFsp(stk[i]->k-1,stk[i]->b,stk[i]->a,stk[i]->c); } else if(stk[i]->tag==4)//出口:出到3或4 { popFsp(); } } return 0; }
- 我的这种方法分析过于细致(粗暴),理解起来有难度,这里推荐盖世馒头的理解方式,即在2和3进入下一次调用时,将该1句话扩写成“4句话”,不停扩写,再依次执行即可。