函數進階-08遞歸

一丶什麼是函數遞歸

函數的嵌套調用是:函數嵌套函數。函數的遞歸調用:它是一種特殊的嵌套調用,可是它在調用一個函數的過程當中,又直接或間接地調用了它自身。python

def foo():
    print('from foo')
    foo()

foo()  # 進入死循環

若是遞歸函數不斷地調用函數自身,那麼這個遞歸函數將會進入一個死循環,所以咱們應該給遞歸函數一個明確的結束條件。dom

1.1 直接調用

直接調用指的是:直接在函數內部調用函數自身。函數

import sys

print(f"最大遞歸層數: {sys.getrecursionlimit()}")

最大遞歸層數: 3000code

import sys

# 修改遞歸層數
sys.setrecursionlimit(10000)
def foo(n):
    print('from foo',n)
    foo(n+1)
foo(0)

1.2 間接調用

間接調用指的是:不在原函數體內調用函數自身,而是經過其餘的方法間接調用函數自身。遞歸

def bar():
    print('from bar')
    foo()
    
def foo():
    print('from foo')
    bar()
    
bar()

遞歸必需要有兩個明確的階段:get

 * 遞推:一層一層遞歸調用下去,進入下一層遞歸的問題規模都將會減少
 * 回溯:遞歸必需要有一個明確的結束條件,在知足該條件開始一層一層回溯。
遞歸的精髓在於經過不斷地重複逼近一個最終的結果。!!!!!it

'''
...
age(5) = age(4) + 2
age(4) = age(3) + 2
age(3) = age(2) + 2
age(2) = age(1) + 2
age(1) = 26


age(n) = age(n-1) +2 
age(1) = 26  # n=1
'''


def age(n):
    if n == 1:
        return 26
    res = age(n-1) + 2
    return res


print(f"age(5): {age(5)}")

age(5): 34io


二丶爲何要用遞歸

遞歸的本質就是乾重復的活,相較於while循環,每次遞歸都會更接近最終要的結果,而後在某次得到結果後依次返回for循環

lis = [1, [2, [3, [4, [5, [6, ]]]]]]

def tell(lis):
    for i in lis:
        if type(i) is list:
            tell(i)
        else:
            print(i)

# print(f"tell(lis): {tell(lis)}")
tell(lis)

1 2 3 4 5 6class


三丶如何用遞歸
查找數字例子:

nums = [1, 3, 7, 11, 22, 34, 55, 78, 111, 115]

for item in nums:
    if item == 10:
        print('find it')
        break
else:
    print('not exists')

not exists
對於上述的列表咱們可能能夠經過一個for循環實現咱們須要的功能,可是當咱們的列表中的元素個數很是多時,咱們還用這種方法,那是極其複雜的,所以咱們能夠考慮使用二分法的思想實現。

from random import randint
nums = [randint(1, 100) for i in range(100)]
nums = sorted(nums)
print(nums)

[1, 2, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 10, 11, 11, 11, 11, 12, 13, 13, 15, 16, 16, 20, 21, 21, 23, 24, 26, 26, 27, 28, 28, 31, 33, 33, 34, 35, 38, 38, 39, 40, 42, 43, 45, 45, 46, 46, 47, 47, 51, 52, 52, 53, 53, 55, 55, 56, 56, 57, 57, 57, 58, 59, 61, 62, 64, 66, 66, 67, 68, 69, 69, 71, 72, 72, 74, 74, 75, 76, 78, 78, 79, 79, 79, 79, 80, 82, 85, 88, 89, 90, 90, 91, 91, 91, 94, 99, 99, 100]

def search(search_num, nums):
    mid_index = len(nums)//2
    print(nums)
    if not nums:
        print('not exists')
        return
    if search_num > nums[mid_index]:
        # in the right
        nums = nums[mid_index+1:]
        search(search_num, nums)
    elif search_num < nums[mid_index]:
        # in the left
        nums = nums[:mid_index]
        search(search_num, nums)
    else:
        print('find it')

search(7, nums)

[1, 2, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 10, 11, 11, 11, 11, 12, 13, 13, 15, 16, 16, 20, 21, 21, 23, 24, 26, 26, 27, 28, 28, 31, 33, 33, 34, 35, 38, 38, 39, 40, 42, 43, 45, 45, 46, 46, 47, 47, 51, 52, 52, 53, 53, 55, 55, 56, 56, 57, 57, 57, 58, 59, 61, 62, 64, 66, 66, 67, 68, 69, 69, 71, 72, 72, 74, 74, 75, 76, 78, 78, 79, 79, 79, 79, 80, 82, 85, 88, 89, 90, 90, 91, 91, 91, 94, 99, 99, 100] [1, 2, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 10, 11, 11, 11, 11, 12, 13, 13, 15, 16, 16, 20, 21, 21, 23, 24, 26, 26, 27, 28, 28, 31, 33, 33, 34, 35, 38, 38, 39, 40, 42, 43, 45, 45, 46, 46, 47, 47] [1, 2, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 10, 11, 11, 11, 11, 12, 13, 13, 15, 16, 16, 20, 21] [1, 2, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7] [6, 6, 7, 7, 7] find it

相關文章
相關標籤/搜索