数据结构_习题3.10 汉诺塔的非递归实现(非 主流解法)

  1. 本题目需要一定汉诺塔的前置知识,这里不提供;
  2. 分析递归代码
    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等价,那我们用一个栈记录数据和状态即可。

  3. 具体实现
    #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;
    }
  4. 我的这种方法分析过于细致(粗暴),理解起来有难度,这里推荐盖世馒头的理解方式,即在2和3进入下一次调用时,将该1句话扩写成“4句话”,不停扩写,再依次执行即可。
posted @ 2023-03-07 10:47  kingdalf  阅读(25)  评论(0)    收藏  举报  来源