函數(shù)遞歸

微信公眾號搜索【程序媛小莊】福荸,關(guān)注半路出家的程序媛如何靠python開發(fā)養(yǎng)家糊口~

引入

函數(shù)既可以嵌套定義也可以嵌套調(diào)用表箭。嵌套定義指的是在定義一個函數(shù)時在該函數(shù)內(nèi)部定義另一個函數(shù);嵌套調(diào)用指的是在調(diào)用一個函數(shù)的過程中函數(shù)內(nèi)部有調(diào)用另一個函數(shù)。而函數(shù)的遞歸調(diào)用指的是在調(diào)用一個函數(shù)的過程中又直接或者間接的調(diào)用該函數(shù)本身比肄。

函數(shù)遞歸介紹

函數(shù)遞歸就是函數(shù)的遞歸調(diào)用,是函數(shù)嵌套調(diào)用的一種特殊形式囊陡,具體就是指在調(diào)用一個函數(shù)的過程中直接或者間接的調(diào)用到本身芳绩,遞歸的本質(zhì)就是循環(huán)做重復(fù)的事情。

在調(diào)用func的過程中又調(diào)用func撞反,這就是直接調(diào)用函數(shù)本身妥色;

image-20210526114004480

在調(diào)用func的過程中調(diào)用foo,而在調(diào)用foo的過程中又調(diào)用func遏片,這就是間接調(diào)用func本身嘹害。

image-20210526134328793

通過上面的分析,兩種情況下的函數(shù)遞歸調(diào)用都是一個無限循環(huán)的過程吮便,Python為了防止函數(shù)遞歸進入無限循環(huán)對函數(shù)遞歸調(diào)用的深度做了限制笔呀,一旦超出限制就會拋出異常。

def foo():
    print('foo')
    func()
def func():
    print('func')
    foo()

func()

'''
程序運行結(jié)果:
RecursionError: maximum recursion depth exceeded while calling a Python object(超過最大遞歸深度)
'''

因此為了避免函數(shù)遞歸調(diào)用報錯线衫,就必須在滿足某中條件的情況下結(jié)束對函數(shù)的遞歸調(diào)用凿可。

def foo(n):
    if n == 1:
        print('遞歸結(jié)束')
        return
    else:
        foo(n-1)
foo(2)

函數(shù)遞歸原理及使用

通過一個簡單的小學(xué)數(shù)學(xué)題說明遞歸的原理及使用。

小一比小二多一個蘋果,小二比小三多一個蘋果枯跑,小三比小四多一個蘋果惨驶,小四有兩個蘋果,問小一有幾個蘋果敛助?

這個題目非常簡單粗卜,解答思路如下:

要想知道小一的蘋果數(shù)量就需要知道小二的蘋果數(shù)量,而小二的蘋果數(shù)量又取決于小三纳击,小三的蘋果數(shù)量又是基于小四的蘋果數(shù)量:
app_num(1) = app_num(2) + 1
app_num(2) = app_num(3) + 1
app_num(3) = app_num(4) + 1
app_num(4) = 2
因此可以總結(jié)出下面的結(jié)論:
app_num(4) = 2 
app_num(x) = app_num(x+1) + 1

很明顯是一個重復(fù)調(diào)用同一種方法的過程续扔,只是參數(shù)不同,也就是一個遞歸的過程焕数,通過上面的分析可以將遞歸過程分為兩個階段 - 回溯和遞推纱昧。

回溯階段:想要計算小一(x=1)的蘋果數(shù)量就需要回溯得到小二(x+1)的蘋果,以此類推堡赔,直到得到小四的蘋果個數(shù)识脆,此時app_num(4)已知,就無需再向前回溯善已。

遞推階段:從小四的蘋果數(shù)量可以推算出小三的蘋果數(shù)量灼捂,從小三的蘋果數(shù)量可以推算出小二的,以此類推换团,一直推算出小一的蘋果數(shù)量為止悉稠,遞歸結(jié)束。需要注意的是艘包,遞歸一定要有結(jié)束條件的猛,這里當(dāng)x=1就是結(jié)束條件。

遞歸的本質(zhì)就是在做重復(fù)的事情辑甜,理論上說遞歸可以解決的問題循環(huán)也都可以解決衰絮,只不過是在某種情況下使用遞歸更容易實現(xiàn)。

image-20210526144333438
def apple_num(x):
    if x == 4:  # 結(jié)束遞歸的條件
        return 2
    return apple_num(x+1) + 1

apple_num1 = apple_num(1)
print(apple_num1)  # 5

Practice

一個嵌套多層的列表要求打印出所有的元素磷醋。

list1 = [[[1, 2], [3, 4], [5, [6, 7], [8, 9, 10], 11, 12], 13]]

def func(items):
    for elements in items:
        if type(elements) is list:
            func(elements)
        else:
            print(elements)
func(list1)

有一個按照從小到大順序排列的數(shù)字列表,需要從該數(shù)字列表中找到我們想要的數(shù)字胡诗,如何更高效邓线?

# 使用二分法:先取出列表的中間位置的值,與需要的數(shù)字進行比較煌恢,如果中間位置的值大于需要的值骇陈,那么就在中間值的左側(cè)2 進行比較,如果小于瑰抵,那么就在中間值的右側(cè)進行比較你雌,如果剛好等于,就輸出值。然后對上述步驟進行循環(huán)

list1 = [0,2,5,7,9,11,34]
find_num = 2
def func(find_num,list1):
    # 輸出每次切分后生成的list1
    print(list1)
    mid_index = len(list1) // 2
    if find_num > list1[mid_index]:
        list1 = list1[mid_index+1:]
        func(find_num,list1)
    elif find_num < list1[mid_index]:
        list1 = list1[:mid_index]
        func(find_num,list1)
    elif find_num == list1[mid_index]:
        print(f'找到了{list1[mid_index]},索引為{mid_index}')
    elif len(list1)  == 0:
        print('不存在這個值')
        return
func(find_num,list1)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末婿崭,一起剝皮案震驚了整個濱河市拨拓,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌氓栈,老刑警劉巖渣磷,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異授瘦,居然都是意外死亡醋界,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進店門提完,熙熙樓的掌柜王于貴愁眉苦臉地迎上來形纺,“玉大人,你說我怎么就攤上這事徒欣〉猜ǎ” “怎么了?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵帚称,是天一觀的道長官研。 經(jīng)常有香客問我,道長闯睹,這世上最難降的妖魔是什么戏羽? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮楼吃,結(jié)果婚禮上始花,老公的妹妹穿的比我還像新娘。我一直安慰自己孩锡,他們只是感情好酷宵,可當(dāng)我...
    茶點故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著躬窜,像睡著了一般浇垦。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上荣挨,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天男韧,我揣著相機與錄音,去河邊找鬼默垄。 笑死此虑,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的口锭。 我是一名探鬼主播朦前,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了韭寸?” 一聲冷哼從身側(cè)響起春哨,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎棒仍,沒想到半個月后悲靴,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡莫其,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年癞尚,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片乱陡。...
    茶點故事閱讀 39,953評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡浇揩,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出憨颠,到底是詐尸還是另有隱情胳徽,我是刑警寧澤,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布爽彤,位于F島的核電站养盗,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏适篙。R本人自食惡果不足惜往核,卻給世界環(huán)境...
    茶點故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望嚷节。 院中可真熱鬧聂儒,春花似錦、人聲如沸硫痰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽效斑。三九已至非春,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間鳍悠,已是汗流浹背税娜。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留藏研,地道東北人。 一個月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓概行,卻偏偏與公主長得像蠢挡,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,901評論 2 355

推薦閱讀更多精彩內(nèi)容