程式呼叫自身的程式設計技巧稱為遞迴(recursion)。
乙個過程或者函式在其定義或說明中又直接或間接地呼叫自身的一種方法,通常把乙個大型複雜的問題層層轉化為乙個與原問題相似的但規模較小的問題來求解。遞迴策略只需少量的程式就可描述出解題過程所需要的多次重複計算,大大減少了程式的**量。
遞迴的能力在於用有限的語句來定義物件的無限集合。一般來說,遞迴需要有邊界條件、遞迴前進段和遞迴返回段。當邊界條件不滿足時,遞迴前進;當邊界條件滿足時,遞迴返回。
漢諾塔(又稱河內塔)問題其實是印度的乙個古老的傳說。
開天闢地的神勃拉瑪(和中國的盤古差不多的神)在乙個廟裡留下了3根金剛石的柱子,第一根柱子上面套著64個圓的金片,最大的乙個金片在底下,其餘金片乙個比乙個小,依次疊上去。廟裡的眾僧不倦地把第一根柱子上的金片乙個乙個地搬到第三根柱子上,規定:可利用中間的第二根柱子來幫助,但每次只能搬乙個金片,而且大的金片不能放在小的金片上面,移動圓片的次數的計算結果非常恐怖:18 446 744 073 709 551 615,眾僧們即便是耗盡畢生精力也不可能完成金片的移動。
輸入:輸入乙個正整數n,表示有n個碟片在第一根柱子上。
輸出:輸出操作序列,格式為move t from x to y。每個操作一行,表示把x柱子上的編號為t的碟片挪到y柱子上。柱子編號為a、b、c,要用最少的操作把所有的盤子從a柱子上轉移到c柱子上。
樣例輸入:
3樣例輸出:
move 1 from a to c
move 2 from a to b
move 1 from c to b
move 3 from a to c
move 1 from b to a
move 2 from b to c
move 1 from a to c
其實演算法非常簡單,當盤子個數為n時,移動的次數應等於2n - 1。後來一位美國學者發現一種出人意料的簡單方法,只要輪流進行兩步操作就可以實現。首先將3根柱子按順序排成「品」字型,把所有的圓盤按從大到小的順序放在柱子a上,根據圓盤的數量確定柱子的排放順序:若n為偶數,按順時針方向依次擺放a、b、c;若n為奇數,按順時針方向依次擺放a、c、b。
按順時針方向把圓盤1從現在的柱子移動到下一根柱子,即當n為偶數時,若圓盤1在柱子a,則把它移動到b;若圓盤1在柱子b,則把它移動到c;若圓盤1在柱子c,則把它移動到柱子a。
接著,把另外兩根柱子上可以移動的圓盤移動到新的柱子上。即把非空柱子上的圓盤移動到空柱子上,當兩根柱子都非空時,移動較小的圓盤。這一步沒有明確規定移動哪個圓盤,你可能以為會有多種可能性,其實不然,可實施的行動是唯一的。
反覆進行1和2操作,最後就能按規定完成漢諾塔的移動。
所以,結果非常簡單,就是按照移動規則向乙個方向移動金片。
例如:3階漢諾塔的移動為:a→
\rightarrow
→c,a→
\rightarrow
→b,c→
\rightarrow
→b,a→
\rightarrow
→c,b→
\rightarrow
→a,b→
\rightarrow
→c,a→
\rightarrow
→c。漢諾塔問題也是程式設計中的經典遞迴問題,下面將給出遞迴的實現源**。
#include #include using namespace std;
void move(int n, char x, char y)
void hannoi(int n, char a, char b, char c)
}int main()
漢諾塔問題
問題 假設有3個分別命名為x,y,z的寶塔,在塔座x上插有n個直徑大小各不相同,從小到大編號為1,2,3。n的圓盤。現要求將x軸上的n個圓盤移至塔座z上 並仍然按同樣的順序疊排,圓盤移動時必須遵循下列規則 1.每次只能移動乙個圓盤 2.圓盤可以插在x,y和z中的任一塔座上 3.任何時刻都不能將乙個較...
漢諾塔問題
問題是 印度的乙個古老的傳說。開天闢地的神勃拉瑪在乙個廟裡留下了三根金剛石的棒,第一根上面套著64個圓的金片,最大的乙個在底下,其餘乙個比乙個小,依次疊上去,廟裡的眾僧不倦地把它們乙個個地從這根棒搬到另一根棒上,規定可利用中間的一根棒作為幫助,但每次只能搬乙個,而且大的不能放在小的上面。解答結果請自...
漢諾塔問題
漢諾塔如下圖所示 需要我們完成的事情是把盤子移動到c,規則就不贅述了。演算法思想 總體來說是利用遞迴完成的。假設 1 a上只有乙個盤子,我們直接移動到c即可 2 a上有兩個盤子,我們把第二個盤子上面的所有盤子 此時只有乙個,比較容易 移動到b,再把第二個盤子移動到目的地c,最後把b上的盤子移動到c ...