1. 程式人生 > >漢諾塔遞迴演算法

漢諾塔遞迴演算法

相信很多人都玩過漢諾塔遊戲,今天來討論下這個遊戲的最優解的程式實現。
假設有A、B、C三根柱子,A是起始柱,B是目標柱,C是中轉柱。

我們先來分析只有一層漢諾塔的情況,這個比較簡單,只需要將A上面的塊放到B上面就行了。

接下來分析兩層漢諾塔的情況,總共分三步,首先將上面的一塊放到C,然後將下面那塊大的放到B,接著將C柱上面的那塊放到B上面。

依次邏輯類推,我們假設N層的漢諾塔,那麼大致也是分為三個步驟,
1.就是將上面的N-1塊放到中轉柱C。這個怎麼移呢,就是將B作為中轉站,將C作為目標站,層數是N-1層

2.然後將A的最後一塊放到目標柱B上面

3.接著將C上面的N-1塊移到目標柱B上面。這時是將C當作起始柱,A當作中轉柱,B還是目標柱,層數是N-1層,這樣就能將C的N-1塊移到B上去。

這個利用到遞迴的思想,先申明函式
hannuo(int n, char x, char y, char z) //n是層數 x是起始柱 y是目標柱 z是中轉柱
那麼這三個步驟可以用用函式表示為

hannuo(n, x, y, z)
{
         hannuo(n-1, x, z, y);       //參見紅字 步驟一
         Printf(“%c -> %c”, x, y);   //將A的最後一塊放到 B    步驟二
         Hannuo(n-1,z, y, x);       //參見紅字 步驟三
}

這個函式還不夠完善,需要遞迴的初始條件完整程式碼如下

hannuo(n, x, y, z)
{
         if(n== 0)
         {
                  //啥都不做
         }
         else
        {
                  hannuo(n-1, x, z, y);       //參見紅字 步驟一
                  Printf(“%c -> %c”, x, y);   //將A的最後一塊放到 B    步驟二
                  Hannuo(n-1,z, y, x);       //參見紅字 步驟三
        }
}

int main(void)
{ Hannuo(5,’A’, ‘B’, ‘C’); Return0; }

分析這個程式碼,這個程式碼的精髓,或者說難點,就在於中間的printf,它的表徵意義就是將起始到目的的這一過程給打印出來,思想是利用遞迴,分成最原始的一小份一小份來列印。

同時我們也可以分析步驟的數量
一層是1
二層是3
以上是我們手動分析的,
然後是我們的N層,他等於N-1層的步驟數+ 一個步驟+ N-1層的步驟數
Num(n) = 2 * num(n-1) + 1
Num(1) = 1
這個可以利用高中知識來解決,亦或者通過前幾項發現規律,找到公式,然後在利用歸納法驗證公式的正確性即可。