学习递归
算法之遞歸
遞歸思想
遞歸就是函數自己調用自己,會使代碼邏輯很清晰,但是Stack Overflow上有說的一句話:“如果使用循環,程序的性能可能更高;如果使用遞歸,程序可能更容易理解。如何選擇要看什么對你來說更重要。
很多排序算法都用到了遞歸,例如快速排序,歸并排序等,具體排序算法代碼參考我之前寫的博客python實現常見排序算法
基線條件和遞歸條件
基線條件
遞歸必須有一個終止條件,避免形成無線循環,這個條件就叫做基線條件。
舉例一般都是一些特殊情況,比如快排時的列表是空列表或者只有一個元素就不需要排序就退出函數即可,這就是基線條件
遞歸條件
指的是函數自己調用自己
簡單的例子
棧
簡單說一下棧:類似槍的彈夾,只能壓入子彈(插入數據),彈出子彈(刪除并讀取),子彈只能后先壓入的最后出來(first in last out)。
調用棧(call stack)
計算機在內部使用被稱為調用棧的棧
函數舉例
內存角度介紹上述函數hello被調用后的計算機處理過程
調用hello計算機分配空間給這個函數存儲函數名和name=maggie,這里給命個名叫greet內存塊
hello內部調用了hello2,同上,計算機一樣分配的內存給他,叫greet2內存塊
如下圖,打印Have you eaten yet miggie后調用的函數被返回,此時greet2內存塊倍彈出。
hello內部調用了bye,同上,計算機一樣分配的內存給他,叫bye內存塊
bye內存塊進來又壓在了greet內存快上,打印完ok,bye后又彈出了
然后整個函數結束,greet內存塊也被彈出
這個棧用于存儲多個函數的變量被稱為調用棧
遞歸調用棧
遞歸函數也使用調用棧,直接看代碼
def fact(x): # jiecheng(3)--> 3! = 3 * 2 * 1 求出3的階乘if x == 1:return 1return x * fact(x-1)
有三個fact的調用,等fact(1)調用結束被彈出,依次彈出,注意每個fact調用都有自己的x變量,在一個函數調用中不能訪問領一個的x變量。
這個棧包含了未完成的函數調用。
缺點:使用棧雖然很方便,但是也要付出代價:存儲詳盡的信息可能占用大量的內存。每個函數調
用都要占用一定的內存,如果棧很高,就意味著計算機存儲了大量函數調用的信息。在這種情況
下,有兩種選擇。
- 重新編寫代碼,轉而使用循環。
- 使用尾遞歸。這里不討論,感興趣可以去查。
小結
- 遞歸指的是調用自己的函數。
- 每個遞歸函數都有兩個條件:基線條件和遞歸條件。
- 棧有兩種操作:壓入和彈出。
- 所有函數調用都進入調用棧。
- 調用棧可能很長,這將占用大量的內存。
總結
- 上一篇: 计算机专业在湖南录取分数,计算机科学与技
- 下一篇: Objective-C成员变量声明方式探