汉诺塔问题(递归)
相傳在古印度圣廟中,有一種被稱為漢諾塔(Hanoi)的游戲。該游戲是在一塊銅板裝置上,有三根桿(編號A、B、C),在A桿自下而上、由大到小按順序放置64個金盤(如下圖)。游戲的目標:把A桿上的金盤全部移到C桿上,并仍保持原有順序疊好。操作規則:每次只能移動一個盤子,并且在移動過程中三根桿上都始終保持大盤在下,小盤在上,操作過程中盤子可以置于A、B、C任一桿上。
分析:對于這樣一個問題,任何人都不可能直接寫出移動盤子的每一步,但我們可以利用下面的方法來解決。設移動盤子數為n,為了將這n個盤子從A桿移動到C桿,可以做以下三步:
(1)以C盤為中介,從A桿將1至n-1號盤移至B桿;
(2)將A桿中剩下的第n號盤移至C桿;
(3)以A桿為中介;從B桿將1至n-1號盤移至C桿。
這樣問題解決了,但實際操作中,只有第二步可直接完成,而第一、三步又成為移動的新問題。以上操作的實質是把移動n個盤子的問題轉化為移動n-1個盤,那一、三步如何解決?事實上,上述方法設盤子數為n, n可為任意數,該法同樣適用于移動n-1個盤。因此,依據上法,可解決n -1個盤子從A桿移到B桿(第一步)或從B桿移到C桿(第三步)問題。現在,問題由移動n個盤子的操作轉化為移動n-2個盤子的操作。依據該原理,層層遞推,即可將原問題轉化為解決移動n -2、n -3… … 3、2,直到移動1個盤的操作,而移動一個盤的操作是可以直接完成的。至此,我們的任務算作是真正完成了。而這種由繁化簡,用簡單的問題和已知的操作運算來解決復雜問題的方法,就是遞歸法。在計算機設計語言中,用遞歸法編寫的程序就是遞歸程序。
以上介紹與思路來自于百度百科
下面來進行代碼實現,由上述思路可得,我們可以將n層的漢諾塔通過遞歸的方式化簡為僅僅幾個盤的操作:
設 X塔為起始塔 Y為輔助塔 Z為目標塔
A:當僅存在一個盤的時候
1.將盤從x塔移動到z塔
B:其他情況
1.用Z塔作為輔助塔將X塔上的n-1個盤子移動到Y塔上
2.將X塔最后一個盤移動到目標塔Z塔上
3.用X塔作為輔助塔將Y塔上的n-1個盤子移動到Z塔上
代碼如下
void move(int n,char x,char y,char z) {if( 1 == n){printf("%c-->%c\n",x,z);}else{move(n-1,x,z,y);printf("%c-->%c\n",x,z);move(n-1,y,x,z);} }運行結果
完整代碼
總結
- 上一篇: 输入任意长度的字符串,反向输出(递归)
- 下一篇: 斐波那契数的两种求法(迭代,递归)