閱讀140 返回首頁    go 阿裏雲 go 技術社區[雲棲]


學習筆記(菜鳥日誌)-"漢諾塔"的遞歸過程

記得大一上C語言課程的時候我還剛剛會用迅雷下載電影,聽不懂,也沒認真聽過,匆匆幾個星期上完了考試。關於“漢諾塔”這樣的字眼,也是僅僅記得是在那個書裏麵出現過而已。最近偶然拿起C語言的書,再次看到了“漢諾塔”遞歸算法的例子,轉好幾圈,終於搞明白了。現在花點時間重新這裏下思路,一則方便自己以後回憶,二則希望能給和我一樣菜的新手們提供參考,三則希望有高人出現對文中不足的地方加以斧正!

   關於“漢諾塔”這個古老的益智遊戲如果不清楚的,到百度百科一下!

 


 

為了方便理解,這裏首先創造三個概念:踏板目標

如果任務是:將A上的圓盤移動至C,我們稱A為源,B為踏板,C為目標。

思路:要是源上隻有一個圓盤,隻直接將圓盤移動至目標。(無需借助踏板過渡)

要是源上有nn>1)個圓盤,則分為下麵三個步驟完成。(借助踏板)

A先將前n-1個移動到踏板上(由上至下的順序) 先移動到踏板上。(任務細分,重複12兩個步驟)

再將最後(n)一個移動至目標。

最後在將踏板上的全部移動至目標。(任務細分,重複12兩個步驟)

就上圖一我們按照上麵的思路遞歸一下整個過程:

第一層:進棧

 任務:A (源) 移動 C(目標) n=3>1,所以借助B(踏板),先將 前兩個先

 移動至B,再將最後一個移動至C,最後將踏板上的移動至C

第二層:進棧

任務:(源)移動 B(目標) n=2>1,所以借助C(踏板),先將前 一個先

 移動C,再將當前任務的最後一個移動至B,最後將踏板C上的移動至B

第三層:進棧

任務:A (源) 移動 C(目標) n=1=1直接將A上最上麵一個移動至C

 


 

出棧。

回溯到第二層:

將當前任務的最後一個移動至B                                             

         
     
   

 


 踏板C上的移動至目標B


 

 


 出棧。

 

回溯到第一層:

  現在已經完成了將A上的上麵兩個移動至踏板B上,現在還剩下兩個步驟:

A上的一個移動到C上,將踏板B上的兩個移動到C上。

1A上的移動到C上。

 


 

B的兩個移動到上。分兩步進行:

第二層:進棧

借助A為踏板,先將B得上一個移動到A上。

 


 

B上的最底下一個移動至目標C

 

圖片

 

踏板A上的移動至目標C   

 

圖片

 

出棧

出棧

自此,整個任務完成!

 

C/C++代碼:
#include "stdio.h"

int main()

{

 void hanoi(int n,char origin,char bridge,char destination);         // hanoi函數的聲明

  intm;

 printf("input the number of diskes:");

 scanf("%d",&m);

 printf("The step to move %d diskes:\n",m);

 hanoi(m,'A','B','C');

 return 0;

}

 

void hanoi(int n,char origin,charbridge,char destination)          // 定義hanoi函數 

   // n個盤從origin座借助bridge,移到 destination

 {

 void move(char x,char y);       //move函數的聲明

 if(n==1)

    move(origin,destination);

 else

    {

     hanoi(n-1,origin,destination,bridge);

    move(origin,destination);

    hanoi(n-1,bridge,origin,destination);

    }

 }

 

 voidmove(char x,char y)           //  定義move函數

 {

  printf("%c-->%c\n",x,y);

 }


 


 


 


 

最後更新:2017-04-02 22:16:36

  上一篇:go java也能寫出點點算法-像C++一樣去優化核心並發的代碼例子1
  下一篇:go eclipse 設置備忘