遞歸小論(3)

請掃碼加公衆號大笑




太多太多的高效算法的受遞歸類型的,快排,堆排序,二叉樹的各類算法,順序統計,BFS,DFS……

遞歸的東西實在太多,似乎計算機科學家們特別鍾愛遞歸

 

爲什麼那麼多的高效算法的都是遞歸的,是因爲遞歸能提高程序的運行速度嗎?

 

事實上,遞歸並不能提高程序運行的速度,反而會降低程序運行的速度。

 

函數棧

遞歸在不斷的調用自身的過程中相當於不斷在內部調用新的函數,操作系統爲了這個就必須的不斷爲其分配空間。

這種申請是動態的,如果遞歸層次不算太深,時間僅僅浪費在爲每個函數的棧幀空間分配地方。也就是在進程內已分配到的頁也許已經夠用。

問題出在往往遞歸程度很深,系統甚至需要爲了這個進程去分配新的頁來存儲這些額外的空間開銷。

另一方面,我們甚至至可能需要考慮到內存和磁盤之間的數據交換,這樣一來程序的速度會更慢。(我們在編程時候使用的內存地址都是邏輯地址,並不是實際的物理地址,一個程序往往得到的內存不會特別大,更不可能達到4G,8G那麼大)。

 

因爲遞歸會減慢程序的速度,國內有的教材甚至把很多遞歸的算法寫了循環的形式。“一切爲了效率”。

 

然而,遞歸還是被廣泛使用着,我相信將來遞歸還會被廣泛使用。

 

原因在於遞歸可以說並不是一項技術,而是一種思考模式,這種pattern是機器思考的模式,(今天看了模仿遊戲有點迷 講圖靈的 特別喜歡那句機器的思考方式只是與人類不同 blablabla)。

 

遞歸簡單講就是,機器手上有這最基本的情況,現在給定任何一種情況,都可以慢慢轉化成最基本的情況,然後在步步爲營,回到最初解決給定的情況。

 

這種思維模式人類很難做到,求4!還算簡單,倘若給一個序列說讓手動使用歸併排序來排序它,我相信我們的速度往往比不上直接看得排序(直接看直接排,根據心情排)

 

把一個遞歸程序翻譯成循環相當於手動排序,只是說“手動”得更高級而已(若是不使用遞歸,那麼就必須得知道怎樣從遞歸底層走到所求問題,也就是對機器怎麼歸併排序要瞭如指掌)。

 

 

與我們相反,計算機很擅長幹這種事情,只要在硬件上沒有問題,它便能確定無疑的一步一步往回走,而且反應速度和人類相比根本不是一個量級

 

被廣泛使用的另一個原因是理論分析方便。

具體點就是分析漸進複雜度問題會快很多,大部分的遞歸問題都遵從分而治之思想,所以最後的遞歸式子往往會變成

T(n)=aT(n/k)+O(*)

這種形式,這種形式已經有了比較系統的主方法能夠解決。

簡單說,遞歸的理論分析如果在有了算法以後往往只是幾分鐘的事情。

 

支持遞歸的另一個原因是使用了遞歸以後,程序的可能性會好很多,如果真的要寫成循環其實是需要很大篇幅的。

然則,換成遞歸以後往往只有幾行,一般遞歸底層定對了就不太會出錯,這樣代碼給別的程序員閱讀的時候,程序員只需要理解遞歸的思路即可,無需煞費心血得理解循環要表達的是什麼,如果存在更換程序員的情況,也不太可能出現說看不懂前一個程序員代碼的尷尬情況。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章