python遞歸

75遞歸

遞歸的核心: 遞進的時候可以達到一個結果,問題規模愈來愈小(不必定要真正的達到); 設置一個條件,可以讓最後一次函數調用結束;dom

遞歸代碼(遞歸更多的是一種思想,用來解決某種問題)函數

遞歸是函數調用函數自己,而後有結束條件code

1、什麼是函數遞歸

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

def foo():
    print ('from foo')
    foo()
foo()
#這個會死循環

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

1.1直接調用

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

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


#輸出:
最大遞歸層數:1000


# 在python3中最大遞歸層數是1000層
import sys
sys.setrecursionlimit(10000)# 能夠修改遞歸層數

def foo(n):
    print('from foo',n)
    foo(n+1)
foo(0)

1.2間接調用

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

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

遞歸必需要又倆個明確的階段class

  1. 遞推:一層一層遞歸調用下去,進入下一層遞歸的問題規模都將會減少。
  2. 回溯:遞歸必需要有一個明確的結束條件,在知足該條件開始一層一層回溯。遞歸的精髓在於經過不斷的重複逼近一個最終的結果。
line = [1 ,2,3,4,5,6]
def howmanyin(lst):
    if lst[1:]:
        print("hello")
        return 1+howmanyin(lst[1:])
    else:
        print('just me')
        return 1
howmanyin(line)


#輸出:
hello
hello
hello
hello
hello
just me
def age(n):
    if n==1:
        return 26
    res = age(n-1)+2
    return res
print(age(5))


#輸出:
34
# 求年齡

# 16/18/20/22/24

# 我知道第一我的的年齡16,我要求出5我的後的年齡-->26


age = 16


# 這就叫遞歸,有空的去看看 漢諾塔  # age_func(5)  = age_func(4) = age_func(3) = age_func(2) = age_func(1) = age_func(0) =26
def age_func(x):  # x的規模在減少  # x = 5 # x =4 # x =3 # x =2  # x = 1 # x = 0
    global age
    if x == 0:
        return age  # 終止函數,age=26,這是age_func(0)
    # age = 18 # age = 20  # age 22  # age = 24 # age = 26
    return age_func(x - 1) + 2  # age_func(4) # age_func(3) # age_func(2) # age_func(1) # age_func(0)


res = age_func(5)
print(res)  # 26

'''
age_func(5) --> age = 18  --> return age_func(4) # return 26
age_func(4) --> age = 20 --> return age_func(3)
age_func(3) --> age = 22 --> return age_func(2) 
age_func(2) --> age = 24 --> return age_func(1)  == return age_func(0)  == return age == return 26
age_func(1) --> age = 26 --> return age_func(0) == return age == return 26

return age # age = 26
'''

'''
age_func(5) --> return age_func(4)+2 == 24+2 =26
age_func(4) --> return age_func(3)+2 == 22+2 = 24
age_func(3) --> return age_func(2)+2 == 20+2 = 22
age_func(2) --> return age_func(1)+2 == 18+2 = 20
age_func(1) --> return age_func(0)+2  == 16+2= 18
'''

def func(n):
    age = 16
    age = age + 2 * n
    return age
res = func(10)
print(res)

爲何要用遞歸

遞歸的本質就是乾重復的活,可是僅僅是普通的重複,咱們使用while循環就能夠了。import

lis = [1,[2,[3,[4,[5,[6,]]]]]]
def tell(lis):
    for i in lis:
        if type(i) is list:
            tell(i)
        else:
            print(i)
tell(lis)


#輸出:
1
2
3
4
5
6

3、如何用遞歸

3.1 二分法的應用

有一個從小到大排列的整型數字列表,咱們判斷某一個數字是否是在這個列表裏面。

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
not exists
not exists
not exists
not exists
not exists
not exists
not exists
not exists
not exists
from random import randint
nums = [randint(1,100) for i in range(100)]
nums = sorted(nums)
print(nums)

#輸出:
[1, 2, 3, 4, 6, 6, 7, 8, 8, 8, 8, 9, 13, 14, 15, 15, 16, 17, 17, 18, 18, 19, 19, 20, 22, 22, 23, 24, 25, 30, 30, 32, 32, 35, 35, 36, 36, 36, 38, 39, 39, 39, 40, 42, 44, 45, 45, 47, 47, 52, 52, 54, 54, 55, 55, 57, 57, 57, 57, 57, 58, 61, 61, 61, 62, 63, 63, 65, 66, 66, 66, 66, 67, 68, 70, 70, 72, 74, 74, 75, 80, 82, 82, 84, 85, 85, 85, 85, 86, 86, 86, 89, 91, 94, 94, 97, 97, 97, 98, 99]
nums = [1, 3, 7, 11, 22, 34, 55, 78, 111, 115]
def search(search_num,nums):
    mid_index = len(nums)//2
    print(nums)
    if not nums:
        print('not exists')
    if search_num>nums[mid_index]:
        nums=nums[mid_index+1:]
        search(search_num,nums)
    elif search_num<nums[mid_index]:
        nums = nums[:mid_index]
        search(search_num,nums)
    else:
        print('find it')
search(7,nums)

#輸出:
[1, 3, 7, 11, 22, 34, 55, 78, 111, 115]
[1, 3, 7, 11, 22]
find it
相關文章
相關標籤/搜索