漢諾塔遞迴演算法
阿新 • • 發佈:2019-01-24
相信很多人都玩過漢諾塔遊戲,今天來討論下這個遊戲的最優解的程式實現。
假設有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
這個可以利用高中知識來解決,亦或者通過前幾項發現規律,找到公式,然後在利用歸納法驗證公式的正確性即可。