漢諾塔問題
有種說法我覺得很好,所謂遞迴,就是利用大道至簡的思想,把乙個大的複雜的問題層層轉換為乙個小的和原問題相似的問題來求解的這樣一種策略。
優點缺點
遞迴給人的感覺是驚豔,它往往能給我們帶來非常簡潔非常直觀的**形勢,從而使我們的編碼大大簡化。
效率往往很低,費時和費記憶體空間。
在遞迴呼叫的過程當中系統為每一層的返回點、區域性量等開闢了棧來儲存。遞迴次數過多容易造成棧溢位。
遞迴的思維確實跟我們的常規思維相逆的,我們通常都是從上而下的思維問題, 而遞迴趨勢從下往上的進行思維。
遞迴的邊界條件,也叫遞迴出口,他決定了遞迴什麼時候結束
遞迴的規則,他必須讓問題逐漸向邊界條件靠攏,否則就會陷入死迴圈。
漢諾塔問題是我見過的最優美的遞迴演算法
漢諾塔問題的解決步驟分三步:
把a除了最下面的盤子以外的所有盤子都移動到b
把最下面的盤子移動到c
再把b上的盤子移動回a
反覆迴圈直到結束。
void
hanno
(int n,
char a,
char b,
char c)
hanno
(n -
1, a, c, b)
;//盤子a上面的 n-1 個盤子從a移動到b
printf
("move disk %d from %c to %c\n"
, n, a, c)
;//把最下面的盤子移動到c
hanno
(n -
1, b, a, c)
;//再把b上的盤子移動回c
}
public
class
hannotower
start
(n -
1, from, to, cache)
; system.out.
println
("move "
+ n +
" from "
+ from +
" to "
+ to)
;start
(n -
1, cache, from, to);}
}
咋一看是不是很扯??
雖然說原則上步驟只有三步,但是那只是原則上啊。。怎麼程式也只有三步??第一步和第三步僅僅只是呼叫本身就解決問題了是什麼鬼??
那些中間過程**去了??
別急,我們慢慢分析,上面我們說了,遞迴的思想是從下往上,從最簡單的問題開始:
if
(n ==1)
hanno
(n -
1, a, c, b)
;//塔a上面的 n-1 個盤子從a移動到b
printf
("move disk %d from %c to %c\n"
, n, a, c)
;//把最下面的盤子移動到塔c
hanno
(n -
1, b, a, c)
;//再把塔b上的盤子移動到塔c
至此,程式結束,實際當中那麼多的步驟,程式只用3行。。。
在我看來,這個問題的精髓在於abc三塔的相對變化,所謂的abc塔只是乙個相對稱呼,在不同層級的遞迴函式中,他們是不同的,也可以簡單理解為,a塔是原點,b塔是快取,c塔是目的。
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
遞迴 演算法學習
遞迴按照遞迴方式可以分為直接遞迴和間接遞迴 1.直接遞迴 遞迴過程p直接呼叫自己 2.間接遞迴 p包含另乙個過程d,而d又呼叫p 遞迴例項 1.漢諾塔問題 include include void hanoi int n,char a,char b,char c int main void 2.八皇...
遞迴演算法學習
所謂的遞迴函式就是在函式體內呼叫本函式。使用遞迴函式一定要注意,處理不當就會進入死迴圈。遞迴函式只有在特定的情況下使用 比如階乘問題 遞迴演算法測試 10的階乘 function f num else console.log 10 的結果為 f 10 請實現乙個fibonacci函式,要求其引數和返...
演算法學習1 遞迴
遞迴 乙個函式呼叫其自身。不同名字空間上的迴圈。注意 使用遞迴策略時,必須有乙個明確的遞迴結束條件,否則遞迴將會無限進行下去。參考 中國大學mooc 演算法基礎 話歪之地的部落格 int factorial int n else 執行f 3 2 f 3 5 f 2 2 f 2 5 f 1 2 f 1...