hanoi塔問題解析(一) c++實現

什麼是hanoi塔?

漢諾塔問題:古代有一個梵塔,塔內有三個座A、B、C,A座上有64個盤子,盤子大小不等,大的在下,小的在上。有一個和尚想把這64個盤子從A座移到B座,但每次只能允許移動一個盤子,並且在移動過程中,3個座上的盤子始終保持大盤在下,小盤在上。如下圖

hanoi塔圖示

問題解答

問題定義
我們把左邊的柱子叫做A,中間的柱子叫做B,右邊的柱子叫做C

hanoi`塔的搬運過程;
i :左邊的柱子只有兩個圓盤

我們先假設在A柱子上只有兩個圓盤,不用圖我們用大腦想象出來最佳流程就是,現在最小的放在B柱子上面然後把大的放在C上面,最後把B柱子上面的小圓盤放在C柱子上。

ii:左邊的柱子上面有三個圓盤
過程如下圖:
在這種情況下,我們可以把上面的兩個圓盤看作是一個,然後又回到了i情況,下圖展示了三個圓盤的轉移過程
三個圓盤的hanoi過程
iii:左邊的柱子上有四個圓盤的時候
在這種情況我們通過作圖做出hanoi的轉移流程是很困難的了,我們可以用在ii中提及到的過程,就是我們先把上面的三個看作是一個,我們第一步的目的就是把前三個移動到中間的柱子上去。下面簡單說一下轉移步驟
1. 將A柱子上面的三個移動到B柱子上面(藉助C柱子)
2. 將A柱子上面中最下面的圓盤移動到C柱子上面
3. 將B柱子上面的所有圓盤移動到C柱子上面(藉助A柱子)
過程如下圖:
四個圓盤的hanoi

問題總結
通過上面的描述我們把hanoi移動的步驟一般化


  1. 將左邊柱子上的N-1個圓盤移動帶中間的柱子上
  2. 將第N個圓盤移動到最右邊的柱子
  3. 將中間柱子上的所有圓盤移動到最右邊的柱子

下面我們給出具體的代碼

void hanoi(int n,char A,char B,char C)
{
    if(n<=1) {
        printf("1 move %c to %c\n",A,C);
        return ;
    }
    hanoi(n-1,A,C,B);
    printf("%d move %c to %c \n",n,A,C);
    hanoi(n-1,B,A,C);
}

不要在看了,這就是全部代碼了。已經沒有了
╭︿︿︿╮
{/ o o /}
( (oo) )
︶ ︶︶
以上是對hanoi塔的總體概述,下面就要聊一聊真正的代碼流程!

代碼詳解

hanoi(n,A,B,C)代表的意義就是講n個圓盤從A移動到C藉助B;
* 當n等於1的時候,就代表把當前A中最大的圓盤直接從A移動到C
* 當n等於2的時候,就調用hanoi(2,A,B,C)也就是執行下面的三個步驟下面就是本文中重點了
1. 調用honoi(1,A,C,B)就是相當於把B柱和C柱交換
2. 執行打印語句,不進行繼續調用。所以不用交換柱子
3. 調用hanoi(1,B,A,C)相當於把B柱和A柱交換
上面的語句可以表述爲:

hanoi(1,A,C,B); 
printf("%d move %c to %c \n",n,A,C);
hanoi(1,B,A,C); 

這就是對代碼的解釋!
當圓盤更多的時候無非就是進行遞歸知道遞歸到上面的狀態,比如有三個圓盤的時候,調用的是:

hanoi(2,A,C,B); //step1
printf("%d move %c to %c \n",n,A,C);
hanoi(2,B,A,C); 

只要理解了前兩個對後面的理解也就不難了!還有一點題外話,當遞歸到程序註釋的step1的時候,會爲後續語句分配空間但不執行

hanoi塔還有一個進階的題目就是判斷當前的狀態時第幾個最優的狀態,將在下篇文章進行講述!

發佈了215 篇原創文章 · 獲贊 197 · 訪問量 50萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章