資料結構學習(C++)——遞迴【1】 (轉)
按照黃皮書的安排,到了該講遞迴的時候了。上網查了查,關於“遞迴”的文章可以說“汗牛充棟”——請原諒我在這裡犯酸,我的意思是,寫別人都寫臭的東西讓大家看,只是浪費大家的時間,所以我下面的東西應該是一些至少我看起來是新的東西,如果覺得有什麼不清楚的,請參閱相關的文章(太多了)。即使這樣,這篇文章還是不能把我想說的寫完,看來我這人真的有廢話的習慣。
看過這樣一道題,問,“結構化設計的三種基礎結構,順序、選擇、迴圈是不是必須的?”當然,你知道這樣一個論斷,只要有這三種就足夠了;但是能不能更少呢?答案是“可以”,原因就是遞迴能取代迴圈的作用,例如下面的對一個陣列裡面元素求和的:
float rsum (float a[], const int n)
{
if (n <= 0) return 0;
else return rsum(a, n – 1) + a[n – 1];
}
實際上就是:
sum = 0;
for (int i = 0; i < n; i++) sum += a[i];
但實際的情況是,任何的一種語言裡面都有迴圈結構,但不是任何的語言都支援遞迴;套用一句話,遞迴是萬能的,但沒有遞迴不是萬萬不能的。然而,我看到現在的某些人,不管什麼問題都要遞迴,明明迴圈是第一個想到的方法,偏偏費盡腦筋去尋找遞迴演算法。對此,我真的不知道該說什麼。
遞迴是演算法嗎
經常的看到“遞迴演算法”、“非遞迴演算法”,這種提法沒有語義上的問題,並且我自己也這樣用——遞迴的演算法。但這也正說明了,遞迴不是演算法,他是一種思想,正是因為某個演算法的指導思想是遞迴的,所以才被稱為遞迴演算法;而一個有遞迴演算法的問題,當你不使用遞迴作為指導思想,這樣得到的演算法就是非遞迴演算法。——而對於迴圈能處理的問題,都有遞迴解法,在這個意義上說,迴圈演算法都可以稱為非遞迴演算法。
我在這咬文嚼字沒什麼別的意思,只是想讓大家知道,能寫出什麼樣的演算法,關鍵是看你編寫演算法時的指導思想。如果一開始就想到了迴圈、迭代的方法,你再費心耗神去找什麼遞迴演算法——即使找到了一種看似“簡潔”的演算法,由於他的低效實際上還是廢物——你還在做這種無用功幹什麼?典型的學究陋習。如果你僅僅想到了遞迴的方法,現在你想用棧來消解掉遞迴,你做的工作僅僅是把做的事自己做了,你又能把提高多少?盲目的迷信消解遞迴就一定能提高效率是無根據的——你做的工作的方法如果不得當的話,甚至還不如系統原來的做法。
從學排列組合那天開始,我所知道的階乘就是這個樣子n! = 1×2×……n。如果讓我來寫階乘的演算法,我也只會想到從1乘到n。再如,斐波那契數列,如果有人用自然語言描述的話,一定是這樣的,開始兩項是0、1,以後的每項都是前面兩項的和。所以讓我寫也只會得到“儲存前兩項,然後相加得到結果”的迭代解法。——現在只要是講到遞迴幾乎就有他們的登場,美其名曰:“定義是遞迴的,所以我們寫遞迴演算法”。我想問的是,定義的遞迴抽象是從哪裡來的?顯然階乘的定義是從一個迴圈過程抽象來的,斐波那契數列的定義是個迭代的抽象。於是,我們先從一個本不是遞迴的事實抽象出一個遞迴的定義,然後我們說,“因為問題的定義是遞迴的,因此我們很容易寫出遞迴演算法”,接著說,“我們也能將這個遞迴演算法轉化為迴圈、迭代演算法”,給人的感覺就像是1÷3=0.33……,0.33……×3=0.99……,然後我們花了好大的心智才明白1=0.99……。
還是有那麼些人樂此不疲,是凡講到遞迴就要提到這兩個,結果,沒有一個學生看到階乘那樣定義沒有疑問的,沒有一個對於那個遞迴的階乘函式抱有欽佩之情的——瞎折騰什麼呢?所以,如果要講遞迴,就要一個令人信服的例子,而這個例子非漢諾塔莫屬。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10748419/viewspace-959473/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 資料結構學習(C++)——遞迴【2】(1) (轉)資料結構C++遞迴
- 資料結構學習(C++)——遞迴【3】(1) (轉)資料結構C++遞迴
- 資料結構學習(C++)——遞迴【2】(2) (轉)資料結構C++遞迴
- 資料結構學習(C++)——遞迴【2】(3) (轉)資料結構C++遞迴
- 資料結構學習(C++)——遞迴【2】(4) (轉)資料結構C++遞迴
- 資料結構學習(C++)——遞迴【3】(2) (轉)資料結構C++遞迴
- 資料結構學習(C++)——迴圈連結串列 (轉)資料結構C++
- 資料結構與演算法學習總結--遞迴資料結構演算法遞迴
- 資料結構-遞迴資料結構遞迴
- 資料結構學習筆記-遞迴求解森林高度資料結構筆記遞迴
- 資料結構學習(C++)——二叉樹【1】 (轉)資料結構C++二叉樹
- 資料結構學習(C++)——序言 (轉)資料結構C++
- 資料結構學習(C++)——圖(總結) (轉)資料結構C++
- 資料結構學習(C++)——樹(總結) (轉)資料結構C++
- 資料結構學習(C++)——圖【1】(基本儲存方法) (轉)資料結構C++
- 資料結構學習(C++)續——排序【1】測試程式 (轉)資料結構C++排序
- 資料結構學習(C++)——線性鏈式結構總結(代後記)【1】 (轉)資料結構C++
- 資料結構5_遞迴資料結構遞迴
- 資料結構學習(C++)——雙向連結串列 (轉)資料結構C++
- 資料結構學習(C++)——稀疏矩陣(十字連結串列【1】) (轉)資料結構C++矩陣
- 資料結構學習(c++)——二叉樹 (轉)資料結構C++二叉樹
- 基礎資料結構之遞迴資料結構遞迴
- 前端學習 資料結構與演算法 快速入門 系列 —— 遞迴前端資料結構演算法遞迴
- 【資料結構】二叉樹遍歷(遞迴+非遞迴)資料結構二叉樹遞迴
- 資料結構學習(C++)——二叉樹【2】 (轉)資料結構C++二叉樹
- 資料結構學習(C++)續——排序【3】交換排序 (轉)資料結構C++排序
- 資料結構學習(C++)——圖【4】(最短路徑) (轉)資料結構C++
- 資料結構學習(C++)——二叉樹【3】 (轉)資料結構C++二叉樹
- 資料結構學習(C++)——圖【2】(DFS和BFS) (轉)資料結構C++
- 資料結構和演算法:遞迴資料結構演算法遞迴
- 資料結構:歸併排序(非遞迴)資料結構排序遞迴
- 資料結構與演算法:遞迴資料結構演算法遞迴
- 關於樹型結構資料遞迴查詢,轉非遞迴查詢的實現遞迴
- 資料結構學習筆記1資料結構筆記
- 【資料結構】遞迴實現連結串列逆序資料結構遞迴
- 資料結構與演算法讀書筆記 - 004 -C++遞迴資料結構演算法筆記C++遞迴
- 資料結構學習(C++)——圖【3】(無向圖)(上) (轉)資料結構C++
- 資料結構學習(C++)——圖【3】(無向圖)(下) (轉)資料結構C++