汉诺塔的非递归实现

void hanoi(int n, int from, int temp, int to)
{
        enum {ROUTINE, RA_A1, RA_A2};
        int *stk;
        int top =0;
        int t;
        int ra;

        stk = (int*)malloc(sizeof(int)*n);
        ra = ROUTINE;

routine:
        if (n==1) printf("move %c -> %c\n", from +'A', to +'A');
        else {
                        stk[top++]= ra;
                        --n;
                        t  = to;
                        to = temp;
                        temp = t;
                        ra = RA_A1;
                        goto routine;
         ra_sw:
                switch(ra) {
                case RA_A1:
                        t = to;
                        to = temp;
                        printf("move %c -> %c\n", from +'A', to +'A');

                        temp = from;
                        from = t;
                        ra = RA_A2;
                        goto routine;
                 case RA_A2:
                        ra= stk[--top];
						t = temp;
						temp = from;
                        from = t;
                        ++n;
                }
        }
        if (top!=0) {
                goto ra_sw;
        }
        free(stk);
}

递归同样可以解决问题,为什么还要用非递归呢?我们必须承认,汉诺塔的运行过程可能会很长。在这个过程中,难免会有外部原因,迫使运行暂时停下来。这就需要有能够“保存进度”的能力。现在变成这样:

struct hanoisave_st {
        int level;
        int from;
        int to;
        int temp;
        int ra;
        int top;
};

struct hanoisave_st hanoi_save;
volatile int powerfail;

void hanoi(int level, int from, int temp, int to)
{
        enum {ROUTINE, RA_A1, RA_A2};
        int n;
        int *stk;
        int top =0;
        int t;
        int ra;
        FILE *fp;


        n= level;
        stk = (int*)malloc(sizeof(int)*n);
        ra = ROUTINE;

routine:
        if (n==1) printf("move %c -> %c\n", from +'A', to +'A');
        else {
                if (powerfail) {
                        hanoi_save.from = from;
                        hanoi_save.to = to;
                        hanoi_save.temp= temp;
                        hanoi_save.level = level;
                        hanoi_save.ra = ra;
                        hanoi_save.top = top;
                        fp = fopen("hanoi.dat", "wb");
                        fwrite(&hanoi_save, sizeof(hanoi_save), 1, fp);
                        fwrite(stk, sizeof(int), top, fp);
                        fclose(fp);
                        free(stk);
                        return ;
                }

                stk[top++]= ra;
                --n;
                t  = to;
                to = temp;
                temp = t;
                ra = RA_A1;
                goto routine;
         ra_sw:
                switch(ra) {
                case RA_A1:
                        t = to;
                        to = temp;
                        printf("move %c -> %c\n", from +'A', to +'A');

                        temp = from;
                        from = t;
                        ra = RA_A2;
                        goto routine;
                 case RA_A2:
                        ra= stk[--top];
               	        t = temp;
                        temp = from;
                        from = t;
                        ++n;
                }
        }
        if (top!=0) {
                goto ra_sw;
        }
        free(stk);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值