遞歸函數
一、定義
在函數中調用自身函數,就稱改函數爲遞歸函數
二、遞歸的特點
1、python從內存角度出發做了限制,遞歸的大遞歸深度默認是997/998
# import sys
# sys.setrecursionlimit(max_recursion)
2、遞歸的優缺點
- 遞歸的缺點 : 佔內存
- 遞歸的優點: 會讓代碼變簡單
三、初識遞歸
A ——> n = 4 age(4) = age(3)+2 = age(n-1) + 2
B ——> n = 3 age(3) = age(2) + 2 = age(n-1) +2
C ——> n = 2 age(2) = age(1) + 2 = age(n-1) +2
D ——> n = 1 age(1) = 40
def find_age(n):
if n == 1:
return 40
else:
return find_age(n-1)+2
print(find_age(4))
>>> 46
def find_age(4):
if 4 == 1:
return 40
else:
return find_age(4-1)+2
def find_age(3):
if 3 == 1:
return 40
else:
return find_age(3-1)+2
def find_age(2):
if 2 == 1:
return 40
else:
return find_age(2-1)+2
def find_age(2):
if 1 == 1:
return 40
else:
return find_age(n-1)+2
return find_age(1)+2 ===> 40+2 = 42
return find_age(2)+2 ===> 42+2 = 44
return find_age(3)+2 ===> 44+2 = 46
四、遞歸進階——二分法查找
1、二分法查找(折半搜索法)原理
折半搜索是一種在有序數組中查找某一特定元素的搜索算法。搜素過程從數組的中間元素開始,如果中間元素正好是要查找的元素,則搜素過程結束;如果某一特定元素大於或者小於中間元素,則在數組大於或小於中間元素的那一半中查找,而且跟開始一樣從中間元素開始比較。這種搜索算法每一次比較都使搜索範圍縮小一半。
2、簡單二分法查找實現
l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88]
def simple_binary_search(lst,target):
mid_index = len(lst)//2
if lst:
if lst[mid_index] > target:
return simple_binary_search(lst[:mid_index],target)
elif lst[mid_index] < target:
return simple_binary_search(lst[mid_index+1:],target)
elif lst[mid_index] == target:
return ('找到了!所查找的值爲:{}'.format(lst[mid_index]))
else:
return ('對不起,沒有您要查找的值!')
print(simple_binary_search(l,66))
3、升級版二分法查找實現
l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88]
def senior_binary_search(lst,target,start=None,end=None):
start = 0 if start is None else start
end = len(lst) if end is None else end
mid_index = start + (end - start)//2
if lst:
if lst[mid_index] > target:
return senior_binary_search(lst,target,start,mid_index-1)
elif lst[mid_index] < target:
return senior_binary_search(lst,target,mid_index+1,end)
elif lst[mid_index] == target:
return ('找到了!所查找的值爲:{},所在索引爲:{}'.format(lst[mid_index],mid_index))
else:
return ('對不起,沒有您要查找的值!')
print(senior_binary_search(l,66))
五、遞歸擴展
def fibonacci(n):
if n == 0 or n == 1:
return 1
else:
return fibonacci(n - 1) + fibonacci(n - 2)
print(fibonacci(0))
print(fibonacci(1))
print(fibonacci(2))
>>> 1
>>> 1
>>> 2
def factorial(n):
if n == 0:
return 1
else:
return factorial(n-1)*n
print(factorial(0))
print(factorial(1))
print(factorial(2))
print(factorial(3))
>>> 1
>>> 1
>>> 2
>>> 6
menu = {
'黑龍江省': {
'哈爾濱市': {
'松北區': {},
'道里區': {},
'南崗區': {},
'香坊區': {}
},
'齊齊哈爾市': {
'龍沙區': {},
'建華區': {},
'鐵鋒區': {},
},
'牡丹江市': {
'愛民區': {},
'東安區': {},
'陽明區': {},
}
},
'吉林省': {
'長春市': {
'南關區': {},
'寬城區': {},
'二道區': {},
},
'吉林市': {
'船營區': {},
'昌邑區': {},
}
},
'遼寧省': {
'瀋陽市': {
'瀋河區': {},
'和平區': {},
'皇姑區': {},
},
'大連市': {
'西崗區': {},
'中山區': {},
}
}
}
def recursion(dic):
while True:
for k in dic:
print(k)
user_input = input('輸入內容(輸入Q或q退出,輸入B或b返回上一級):\n>>>').strip()
if user_input.lower() == 'b' or user_input.lower() == 'q':
return user_input
elif user_input in dic.keys() and dic[user_input]:
res = recursion(dic[user_input])
if res == 'q':
return 'q'
elif (not dic.get(user_input)) or (not dic[user_input]) :
continue
recursion(menu)