漢諾塔非遞歸實現 C語言版

漢諾塔非遞歸實現 C語言版

我上一篇博客是漢諾塔C語言遞歸實現,非遞歸和遞歸想法一樣。這裏不再贅述,直接鏈接轉到:

漢諾塔遞歸實現 C語言版

遞歸實現固然好理解,但是n的值越大,空間和時間上都是極大的消耗,最終可能導致程序直接崩潰。
在以後的做題或者是面試中,不推薦用遞歸方法做,所以要寫出對應的非遞歸方法。

某次上課無意間聽到老師說了這樣一句話:任何遞歸法都可以用循環的方法進行非遞歸實現,然後回頭找了找漢諾塔非遞歸的資料,整理整理,搞出了一個c實現的非遞歸方法

#include<stdio.h>
#include <stdlib.h>
#define MaxSize 100
typedef struct{
     int N;
     char A;        //起始柱
     char B;        //藉助柱
     char C;        //目標柱
}ElementType;
typedef struct {
    ElementType Data[MaxSize];
    int top;
}Stack;//漢諾塔問題的結構類型
void Push(Stack *PtrS, ElementType item){
     //入棧操作
     if (PtrS->top == MaxSize)
     {
         printf("The stack is full!\n");
         return;
     }
     else
     {
         PtrS->Data[++(PtrS->top)] = item;
         return;
     }
}
ElementType Pop(Stack *PtrS){
    if (PtrS->top == -1)
      {
          printf("The stack is empty!\n");
          exit(1);   //直接終止程序,一般不會出現這個錯誤
      }
      else
      {
          PtrS->top--;
         return (PtrS->Data[PtrS->top + 1]);        //或者是return PtrS->Data[PtrS->top--];
      }
}
//藉助棧的非遞歸實現
 void Hanoi(int n){
    ElementType P, toPush;
    Stack S;
     
    P.N = n; P.A = 'a'; P.B = 'b'; P.C = 'c';
    S.top = -1;

     Push(&S, P);
     while (S.top != -1)        //當堆棧不爲空時
     {
         P = Pop(&S);//出棧
         if (P.N == 1)//當只剩一個盤子時,直接由當前柱移動到目的柱
             printf("%c -> %c\n", P.A, P.C);
         else
         {
             toPush.N = P.N - 1;
             toPush.A = P.B; toPush.B = P.A; toPush.C = P.C;
             Push(&S, toPush);        //將第三步(n - 1, b, a, c)入棧
             toPush.N = 1;
             toPush.A = P.A; toPush.B = P.B; toPush.C = P.C;
             Push(&S, toPush);        //將第二步1, a, b, c)入棧
             toPush.N = P.N - 1;
             toPush.A = P.A; toPush.B = P.C; toPush.C = P.B;
             Push(&S, toPush);        //將第一步(n - 1, a, c, b)入棧
         }
     }
 }
int main(){
    int n;
    scanf("%d", &n);
    if (n <= 0)return 0;
    else Hanoi(n);
}

還是三個步驟:
1.將n-1個盤子由a柱藉助c柱移動到b柱
2.將最下面的盤子由a柱直接移動到c柱
3.將那n-1個盤子在由b柱藉助a柱移動到c柱

因爲這個是出棧時的操作,所以入棧時要到着寫

簡要解釋一下(因爲跟遞歸思路差不多)

如果n不等於一時,就意味着,以上的n-1個盤子,都要做上述所說的三個步驟,知道n等於1時,直接移動到目的柱。
因此,移動次數最多的是最上邊的那個盤子,移動次數最少的是最下面的那個盤子,只需要移動一次

利用結構體數組更便於理解。

本文爲原創,如有問題歡迎評論區留言。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章