python--遞歸、二分查找算法
遞歸
初識遞歸
遞歸的定義——在一個函數裏再調用這個函數本身
現在我們已經大概知道剛剛講的story函數做了什麽,就是在一個函數裏再調用這個函數本身,這種魔性的使用函數的方式就叫做遞歸。
剛剛我們就已經寫了一個最簡單的遞歸函數。
遞歸的最大深度——997
正如你們剛剛看到的,遞歸函數如果不受到外力的阻止會一直執行下去。但是我們之前已經說過關於函數調用的問題,每一次函數調用都會產生一個屬於它自己的名稱空間,如果一直調用下去,就會造成名稱空間占用太多內存的問題,於是python為了杜絕此類現象,強制的將遞歸層數控制在了997(只要997!你買不了吃虧,買不了上當...).
遞歸函數與三級菜單
menu = { ‘北京‘: { ‘海澱‘: { ‘五道口‘: { ‘soho‘: {}, ‘網易‘: {}, ‘google‘: {} }, ‘中關村‘: { ‘愛奇藝‘: {}, ‘汽車之家‘: {}, ‘youku‘: {}, }, ‘上地‘: { ‘百度‘: {}, }, }, ‘昌平‘: { ‘沙河‘: { ‘老男孩‘: {}, ‘北航‘: {}, }, ‘天通苑‘: {}, ‘回龍觀‘: {}, }, ‘朝陽‘: {}, ‘東城‘: {}, }, ‘上海‘: { ‘閔行‘: { "人民廣場": { ‘炸雞店‘: {} } }, ‘閘北‘: { ‘火車戰‘: { ‘攜程‘: {} } }, ‘浦東‘: {}, }, ‘山東‘: {}, }
1 def threeLM(dic):
2 while True:
3 for k in dic:print(k)
4 key = input(‘input>>‘).strip()
5 if key == ‘b‘ or key == ‘q‘:return key
6 elif key in dic.keys() and dic[key]:
7 ret = threeLM(dic[key])
8 if ret == ‘q‘: return ‘q‘
9 elif (not dic.get(key)) or (not dic[key]) :
10 continue
11
12 threeLM(menu)
二分法
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]
你觀察這個列表,這是不是一個從小到大排序的有序列表呀?
如果這樣,假如我要找的數比列表中間的數還大,是不是我直接在列表的後半邊找就行了?
這就是二分查找算法!
貼上兩段代碼:
一:簡單二分法
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 func(l,aim):
mid = (len(l)-1)//2
if l:
if aim > l[mid]:
func(l[mid+1:],aim)
elif aim < l[mid]:
func(l[:mid],aim)
elif aim == l[mid]:
print("bingo",mid)
else: print(‘找不到‘)
func(l,66)
func(l,6)
二:
升級版二分法
def func(l, aim,start = 0,end = len(l)-1 ):
mid = (start+end)//2
if not l[start:end+1]:
return
elif aim > l[mid]:
return func(l,aim,mid+1,end)
elif aim < l[mid]:
return func(l,aim,start,mid-1)
elif aim == l[mid]:
print("bingo")
return mid
index = func(l,68)
print(index)
#遞歸解決的問題
#就是通過參數,來控制每一次縮小計算的規模
#適合的場景:數據的規模在減小 解決問題的思路在改變
#總結:結束遞歸的標誌:return
#用處:未來遇到很多遞歸的地方,算法(排序算法,金融類) 9
#遞歸函數:在一個函數裏調用自己
#最大遞歸層數做了一個限制:997
#最大層數限制是python默認的。可以做修改
#但是不建議修改
#import sys #所以和python相關的設置和放到
# def a():
# print("ff")
# a()
# a()
#
# import sys
# sys.setrecursionlimit(10000000)
# n =1
# def a():
# global n
# n += 1
# # print("ff")
# print(n)
# a()
# a()
# def age(n):
# if n == 1:
# return 40
# else:
# ret = age(n-1)
# return ret + 2
# print(age(5))
# def age(5):
# if 5 == 1:
# return 40
# else:
# ret = 46
# return ret + 2
#
# def age(4):
# if 5 == 1:
# return 40
# else:
# ret = 44
# return ret + 2
#
# def age(3):
# if 5 == 1:
# return 40
# else:
# ret = 42
# return 44
#
# def age(2):
# if 5 == 1:
# return 40
# else:
# ret = 40
# return 42
#
# def age(1):
# if 5 == 1:
# return 40
#age(1) == 40
#
# l = [1,2,3,4,5,6,7,8,9,10,11,12,23,45,67,89,100]
# def find(l,aim):
# mid = len(l)//2
# if l[mid] > aim:
# ll=l[:mid]
# return find(ll,aim)
# elif l[mid] < aim:
# ll= l[mid+1:]
# return find(ll,aim)
# else:
# return l.index(aim)
# print(find(l,11))
#
# def a(num):
# if num %2.2 == 0:
# num = num // 2
# return a(num)
# else:
# return num
# print(a(8.8))
menu = {
‘北京‘: {
‘海澱‘: {
‘五道口‘: {
‘soho‘: {},
‘網易‘: {},
‘google‘: {}
},
‘中關村‘: {
‘愛奇藝‘: {},
‘汽車之家‘: {},
‘youku‘: {},
},
‘上地‘: {
‘百度‘: {},
},
},
‘昌平‘: {
‘沙河‘: {
‘老男孩‘: {},
‘北航‘: {},
},
‘天通苑‘: {},
‘回龍觀‘: {},
},
‘朝陽‘: {},
‘東城‘: {},
},
‘上海‘: { ‘閔行‘: { "人民廣場": { ‘炸雞店‘: {} } }, ‘閘北‘: { ‘火車戰‘: { ‘攜程‘: {} } }, ‘浦東‘: {}, }, ‘山東‘: {},}# def ak(men):# while True:# for key in men:# print(key)# k = input("input>>>")# return ak(men[k])# print(ak(menu))# def ak(men):# # print("大區信息")# while True:# for key in men:# print(key)# k = input("input(quit或者exit退出)>>>")# if k =="quit" or k == "exit":# return k# else:# return ak(men[k])# print(ak(menu))#
python--遞歸、二分查找算法