python递归和循环的区别_递归与伪递归区别,Python 实现递归与尾递归
遞歸函數在函數內部,可以調用其他函數。如果一個函數在內部調用自身本身,這個函數就是遞歸函
數。(1) 遞歸就是在過程或函數里調用自身。(2) 在使用遞歸策略時,必須有一個明確的遞歸結束條件,稱為遞歸出口。
遞歸一般用于解決三類問題:
(1)數據的定義是按遞歸定義的。(n的階乘)
(2)問題解法按遞歸實現。(回溯)
(3)數據的結構形式是按遞歸定義的。(二叉樹的遍歷,圖的搜索)
遞歸的缺點:
遞歸解題相對常用的算法如普通循環等,運行效率較低。因此,應該盡量避免使用遞歸,除非沒有更好的算法或者某種特定情況,遞歸更為適合的時候。在遞歸調用的過程當中系統為每一層的返回點、局部量等開辟了棧來存儲,因此遞歸次數過多容易造成棧溢出。
#遞歸函數??act(n)?=?n!?=?1?x?2?x?3?x?...?x?(n-1)?x?n?=?(n-1)!?x?n?=?fact(n-1)?x?ndef?fact(n):if?n==1:return?1return?n*fact(n-1)
尾遞歸是指,在函數返回的時候,調用自身本身,并且,return 語句不能包含表達式。這樣,編譯器或者解釋器就可以把尾遞歸做優化,使遞歸本身無論調用多少次,都只占用一個棧幀,不會出現棧溢出的情況。
上面的fact(n)函數由于return n * fact(n ‐ 1)引入了乘法表達式,所以就不是尾遞歸了。要改成尾遞歸方式,需要多一點代碼,主要是要把每一步的乘積傳入到遞歸函數中:
#定義尾遞歸函數def?fact(n):return??fact_iter(n,1)def?fact_iter(num,product):if?num?==1:return?productreturn?fact_iter(num-1,num*product)#測試print?fact_iter(5,1)120可以看到,return?fact_iter(num?‐?1,?num?*?product)僅返回遞歸函數本身,num?‐?1?和num?*?product?在函數調用前就會被計算,不影響函數調用。fact(5)對應的fact_iter(5,?1)的調用如下:?'''#實現過程解讀===>?fact_iter(5,?1)===>?fact_iter(4,?5)===>?fact_iter(3,?20)===>?fact_iter(2,?60)===>?fact_iter(1,?120)===>?120'''
尾遞歸調用時,如果做了優化,棧不會增長,因此,無論多少次調用也不會導致棧溢出。遺憾的是,大多數編程語言沒有針對尾遞歸做優化,Python 解釋器也沒有做優化,所以,即使把上面的fact(n)函數改成尾遞歸方式,也會導致棧溢出。
小結
使用遞歸函數的優點是邏輯簡單清晰,缺點是過深的調用會導致棧溢出。
針對尾遞歸優化的語言可以通過尾遞歸防止棧溢出。尾遞歸事實上和循環是等價的,沒有循
環語句的編程語言只能通過尾遞歸實現循環。
總結
以上是生活随笔為你收集整理的python递归和循环的区别_递归与伪递归区别,Python 实现递归与尾递归的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python学习指令_由Python到深
- 下一篇: websocket python爬虫_p