Python遞歸函數


 

  本篇主要介紹Python中函數的遞歸,還是從三個方面了解:什么是遞歸;遞歸有什么好處;遞歸的具體用法是什么樣的;

一、什么是遞歸?

  在函數內部,可以調用其他函數。如果一個函數在內部調用自身本身,這個函數就是遞歸函數。記住哦->在函數內部調用其他函數不是函數的嵌套,而在函數內部定義子函數才是函數的嵌套。

遞歸的特性:

  1、遞歸函數必須有一個明確的結束條件。

  2、每進入更深一層的遞歸時,問題規模相對於上一次遞歸都應減少

  3、相鄰兩次重復之間有緊密的聯系,前一次要為后一次做准備(通常前一次的輸出就作為后一次的輸入)。

  4、遞歸效率不高,遞歸層次過多會導致棧溢出(在計算機中,函數調用是通過棧(stack)這種數據結構實現的,每當進入一個函數調用,棧就會加一層棧幀,每當函數返回,棧就會減一層棧幀。由於棧的大小不是無限的,所以,遞歸調用的次數過多,會導致棧溢出)

 

  先看一個例子,一個關於實現疊加的兩種方法的例子:

import sys
#通過循環來實現疊加
def sum1(n):
    '''
    1 to n,The sum function
    '''
    sum = 0
    for i in range(1,n + 1):
        sum += i
    return sum

#通過函數的遞歸來實現疊加
def sum2(n):
    '''
    1 to n,The sum function
    '''
    if n > 0:
        return n + sum_recu(n - 1)    #調用函數自身
    else:
        return 0

print("循環疊加-->",sum1(100))
print("遞歸疊加-->",sum2(100))

#兩者實現的效果均是:5050

   從上述例子中可以看出,兩者都可以實現疊加的效果。那么后者相對前者有什么優缺點呢?

 

二、遞歸函數有啥優缺點?

  遞歸函數的優點:定義簡單,邏輯清晰。理論上,所有的遞歸函數都可以寫成循環的方式,但循環的邏輯不如遞歸清晰。

  遞歸函數的缺點:使用遞歸函數需要注意防止棧溢出。在計算機中,函數調用是通過棧(stack)這種數據結構實現的,每當進入一個函數調用,棧就會加一層棧幀,每當函數返回,棧就會減一層棧幀。由於棧的大小不是無限的,所以,遞歸調用的次數過多,會導致棧溢出。

  把上面的遞歸求和函數的參數改成10000就導致棧溢出!

  當然也可以通過尾遞歸來對遞歸的棧溢出進行優化。這里就不詳細介紹了。請參考:http://www.open-open.com/lib/view/open1480494663229.html

三、通過實例來介紹函數遞歸:

  下面我們通過一個問路的例子,更好的理解遞歸:

#假如街上有這么一群人,我想問知道長沙的小吃街在哪。其中只有狗菲(大吃貨)知道在哪。
names=["","劉二","張三","李四","狗菲","王五"]
#問路
def ask_way(lis):
    #街上就我一個人的情況下
    if len(lis)==1:
        return "沒有人知道這個地方在哪。"
    #街上不只我一個人的情況下,先問第一個人
    name=lis.pop(0)
    #如果這個人是狗菲,那么問到路,遞歸結束
    if name=="狗菲":
        return "狗菲說:長沙的小吃街在天心區南門口!!"
    #如果這個人不知道路,就去問下一個人,下一個人就好把結果告訴這個人。
    print("<%s>問:你[%s]好,請問你知道長沙的小吃街在哪嗎?" % (name, lis[0]))
    print("不好意思,我幫您問一下%s,他可能會知道!!\n"%lis[0])
    res=ask_way(lis)
    if name != "":
        print("<%s>說:%s" % (name, res))
    return res

#輸出結果為:
"""
<我>問:你[劉二]好,請問你知道長沙的小吃街在哪嗎?
不好意思,我幫您問一下劉二,他可能會知道!!

<劉二>問:你[張三]好,請問你知道長沙的小吃街在哪嗎?
不好意思,我幫您問一下張三,他可能會知道!!

<張三>問:你[李四]好,請問你知道長沙的小吃街在哪嗎?
不好意思,我幫您問一下李四,他可能會知道!!

<李四>問:你[狗菲]好,請問你知道長沙的小吃街在哪嗎?
不好意思,我幫您問一下狗菲,他可能會知道!!

<李四>說:狗菲說:長沙的小吃街在天心區南門口!!
<張三>說:狗菲說:長沙的小吃街在天心區南門口!!
<劉二>說:狗菲說:長沙的小吃街在天心區南門口!!

狗菲說:長沙的小吃街在天心區南門口!!
"""

  其實用圖來表示就是:

  

  從上面的圖示我們也可以知道:遞歸值的返回時返回到上一層,而其他的層在執行的過程中,均處於等待答案的過程中。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM