03-递归
數據結構和算法
基于《算法圖解》—Aditya Bhargava和《數據結構》—嚴蔚敏
第3章 遞歸
3.1 遞歸
假設在一堆嵌套的盒子里找鑰匙,對比循環和遞歸。
使用循環解決:
使用遞歸解決:
兩種辦法的作用相同;但遞歸可以讓解決方案更清晰,并沒有性能上的優勢;使用循環的性能更好。
3.2 基線條件和遞歸條件
- 編寫遞歸函數時,必須告訴它何時停止遞歸,否則會進入無限循環。
- 每個遞歸函數都有兩部分:基線條件(base case)和遞歸條件(recursive case)。
- 遞歸條件指的是函數調用自己。
- 基線條件指的是函數不再調用自己,避免形成無限循環。
3.3 棧
棧是一種簡單的數據結構。具有兩種操作:壓入(插入)和彈出(讀取并刪除)。
3.3.1 調用棧(call stack)
用于存儲多個函數的變量。
計算機為每個函數調用分配一個內存塊,并使用一個棧來表示這些內存塊;其中第二個內存塊位于第一個內存塊上面,棧頂函數調用返回后,內存塊被彈出。
當我們調用函數greet2時,函數greet只執行了一部分:調用另一個函數時,當前函數暫時并處于未完成狀態;該函數的所有變量的值都還在內存中;執行完函數greet2后,回到函數greet,并從暫時離開的地方開始接著往下執行。
3.3.2 遞歸調用棧
#階乘 def fact(x):if x == 1:return 1else:return x * fact(x-1)
每個fact調用都有自己的x變量。在一個函數調用中不能訪問另一個的x變量。
3.3.3 使用棧的代價
使用棧雖然方便,但存儲詳盡的信息可能占用大量的內存。每個函數調用都要占用一定的內存,如果棧很高,就意味著計算機存儲了大量函數調用的信息。
3.4 小結
- 遞歸指的是調用自己的函數。
- 每個遞歸函數都有兩個條件:基線條件和遞歸條件。
- 棧有兩種操作:壓入和彈出。
- 所有函數調用都進入調用棧。
- 調用棧可能很長,這將占用大量的內存。
——持續修改完善中…
總結