汉诺塔的非递归实现

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);
}

你可能感兴趣的:(汉诺塔,非递归,C语言)