從漢諾塔問題看遞迴

2021-08-08 12:15:01 字數 1527 閱讀 8928

看《資料結構,演算法與應用c++語言描述》一文中第185頁出現了乙個漢諾塔問題。這是個遞迴問題,想了好久終於在今天想懂了一點點(用起來說實在的還是濛濛的)。

#include

#include

#include

using namespace std;

void move(int n,int x,int y,int z)

}void main()

首先要明確乙個問題,遞迴函式需要有個範圍,不然就進入無限死迴圈中。這裡我們主要對move函式進行講解。

我們的目的是將盤子通過a盤子,轉換到c盤子。

當 n =2 時 ,我們首先執行move(2,『a』,'b','c');

因為 n != 1 說以又將執行一遍 move(1,'a','c',b');(注意這裡並不是a到c了,是a到b);

這時將a移動到b完成,接著返回,執行 move(2,'a','b','c')中的第三條指令,將a移動到c,

接下來將執行move(2,'a','b','c');中的第4條指令,此時接著呼叫move(1,'b','a','c')將b移動到c上;

返回執行完成。所用實際步驟是3步。

當n = 3 時,同理我們首先要執行move(3,'a','b','c');

因為n != 1將執行move(2,『a』,『c』,『b』);

因為n!= 1又將執行move(1,'a','b','c');

這時n =1 將a移動到c ;返回至move(2,'a』,'c','b');

接下來接著move(2,『a』,『c』,『b』)後面的步驟3,將a移動到b

接下來只想move (2,『a』,'c','b');呼叫move(1,'c','a','b'),將a移動至c;

再調回至move(3,a,b,c);再按步驟執行後面那部分。

這麼看實在是麻煩,根據資料結構中樹的原理,我個人總結了貼吧上都沒有的遞推方法(因為第一次用沒有找到怎麼上傳的功能,所以只能把思路說說)。

首先move(3,a,b,c)有三個分支,move(2,a,c,b)      cout << a ---- c   move(2,b,c,a);再繼續對每個節點繼續分,直至n =1 ;

梳理流程上,採用後序遍歷的方法,對每個節點葉子採用從左向右的順序方法遍歷,再訪問根節點。

根據數學歸納法的說明證明 n = 1 ,2 時成立 當 n 大於2時的某點也成立,那麼  所有的n都成立 ,所以成立。

所以針對這move函式我們總結出

若想將資料根據堆疊的方法從a移動到c上,就要先將a通過c移動到b上,將a移動到c上,再由b通過a移動到c上的方法。

當然跳出該問題,我們還可以看到其他的問題,例如有7個層的話如何將之從a移動到c上呢?我們根據數學歸納法來解決,當只有一層時我們只需要1步將a移動到c。如果有兩個旗子呢,我們將a中前1個旗子移動到b上,再將最後乙個移動到c上,再將b移動到c上,需要1+1+1 =3步。3個的話我們先將前兩個從a移動到b,再將a最後乙個移動到c,再將b上的移動到c,算數變成了3+3+1 = 7 ,所以推出四個旗子有7+7+1 =15 步 ,5個旗子有 15+15 +1 =31 步最短的步驟。

從漢諾塔看遞迴

很開心今天搞明白了漢諾塔的方法遞迴。走了很多的彎路,今天分享自己的一些思考的過程以及結果。希望對有需要的同學們有所幫助。題目 漢諾塔由三根柱子 分別用x y z表示 和n個大小互不相同的空心盤子組成。一開始n個盤子都摞在柱子x上,大的在下面,小的在上面,形成了乙個塔狀的錐形體。對漢諾塔的一次合法的操...

漢諾塔問題(遞迴)

題目描述 對於傳統的漢諾塔遊戲我們做乙個拓展,我們有從大到小放置的n個圓盤,開始時所有圓盤都放在左邊的柱子上,按照漢諾塔遊戲的要求我們要把所有的圓盤都移到右邊的柱子上,請實現乙個函式列印最優移動軌跡。給定乙個int n,表示有n個圓盤。請返回乙個string陣列,其中的元素依次為每次移動的描述。描述...

漢諾塔問題(遞迴)

問題 漢諾塔問題 解法 遞迴求解 思路 先把n 1從a移動b 在把第n個從a移到c 使用遞迴使得 變得簡單 複雜度 2的n次方 1 includeint step 1 void hanoi int level,char a,char b,char c 1 當盤子數大於1時,先把n 1個從a借助c移動...