python小白-day4递归和算法基础
遞歸&算法基礎(chǔ)
一、遞歸
遞歸函數(shù)的優(yōu)點(diǎn)是定義簡單,邏輯清晰。理論上,所有的遞歸函數(shù)都可以寫成循環(huán)的方式,但循環(huán)的邏輯不如遞歸清晰。
使用遞歸函數(shù)需要注意防止棧溢出。在計(jì)算機(jī)中,函數(shù)調(diào)用是通過棧(stack)這種數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)的,每當(dāng)進(jìn)入一個函數(shù)調(diào)用,棧就會加一層棧幀,每當(dāng)函數(shù)返回,棧就會減一層棧幀。由于棧的大小不是無限的,所以,遞歸調(diào)用的次數(shù)過多,會導(dǎo)致棧溢出。
| 12345678 | def calc(n):????print(n)????if n/2>1:????????ret = calc(n/2)????????print(ret)????print('N',n)????return ncalc(10) |
二、二分法
主要使用折半查找算法和利用遞歸函數(shù)來實(shí)現(xiàn)。因?yàn)槊看稳≈虚g數(shù)字后,都會產(chǎn)生左右兩個數(shù)組,
需要使用隊(duì)列把數(shù)組存起來,然后輸入遞歸函數(shù)內(nèi)計(jì)算中間數(shù)字。遞歸函數(shù)終止條件是:1)中間數(shù)字
與左邊最小的數(shù)字相鄰;2)中間數(shù)字與右邊最大的數(shù)字相鄰。
代碼實(shí)現(xiàn):
| 12345678910111213141516 | def binary_search(data_source,find_num):????mid = int(len(data_source)/2)????if len(data_source) >1:????????if data_source[mid] > find_num:????????????binary_search(data_source[:mid],find_num)????????????print('data in left of [%s]'%data_source[mid])????????elif data_source[mid] < find_num:????????????binary_search(data_source[mid:],find_num)????????????print('data in right of [%s]'%data_source[mid])????????else:????????????print('found',data_source[mid])????else:????????print('cannot found')if __name__ == '__main__':????data = list(range(1,600000))????binary_search(data,75000) |
三、用遞歸實(shí)現(xiàn)斐波那契數(shù)列
| 12345678 | def fun(arg0,arg1,stop):????if arg0 == 0:????????print(arg0,arg1)????arg2 = arg0 + arg1????if arg2 < stop :????????print(arg2)????????fun(arg1,arg2,stop)fun(0,1,1000) |
四、二維數(shù)組轉(zhuǎn)換
需求:生成一個4*4的二維數(shù)組并將其順時針旋轉(zhuǎn)90度
核心思想:數(shù)組下標(biāo)的對應(yīng)關(guān)系可以一一對應(yīng)轉(zhuǎn)換。
| 1234567891011 | data = [[col for col in range(4)] for row in range(4)]for i in data:????print(i)for r_index,row in enumerate(data):????for c_index in range(r_index,len(row)):????????tmp = data[c_index][r_index]????????data[c_index][r_index] = row[c_index]????????data[r_index][c_index] = tmpprint('--------------------')for i in data:????print(i) |
五、冒泡排序
| 12345678910 | #!/usr/bin/env pythondata = [10,4,33,21,54,3,8,11,5,22,2,1,17,13,6]for i in range(len(data)):????for j in range(len(data)-1-i):????????if data[j] > data[j+1]:????????????tmp = data[j+1]????????????data[j+1] = data[j]? ????????????data[j] = tmp????????????#data[j],data[j+1] = data[j+1],data[j] #這種方式也可以????print(data) |
六、時間復(fù)雜度
(1)時間頻度?一個算法執(zhí)行所耗費(fèi)的時間,從理論上是不能算出來的,必須上機(jī)運(yùn)行測試才能知道。但我們不可能也沒有必要對每個算法都上機(jī)測試,只需知道哪個算法花費(fèi)的時間多,哪個算法花費(fèi)的時間少就可以了。并且一個算法花費(fèi)的時間與算法中語句的執(zhí)行次數(shù)成正比例,哪個算法中語句執(zhí)行次數(shù)多,它花費(fèi)時間就多。一個算法中的語句執(zhí)行次數(shù)稱為語句頻度或時間頻度。記為T(n)。(2)時間復(fù)雜度?在剛才提到的時間頻度中,n稱為問題的規(guī)模,當(dāng)n不斷變化時,時間頻度T(n)也會不斷變化。但有時我們想知道它變化時呈現(xiàn)什么規(guī)律。為此,我們引入時間復(fù)雜度概念。?一般情況下,算法中基本操作重復(fù)執(zhí)行的次數(shù)是問題規(guī)模n的某個函數(shù),用T(n)表示,若有某個輔助函數(shù)f(n),使得當(dāng)n趨近于無窮大時,T(n)/f(n)的極限值為不等于零的常數(shù),則稱f(n)是T(n)的同數(shù)量級函數(shù)。記作T(n)=O(f(n)),稱O(f(n))?為算法的漸進(jìn)時間復(fù)雜度,簡稱時間復(fù)雜度。指數(shù)時間指的是一個問題求解所需要的計(jì)算時間m(n),依輸入數(shù)據(jù)的大小而呈指數(shù)成長(即輸入數(shù)據(jù)的數(shù)量依線性成長,所花的時間將會以指數(shù)成長)| 12345 | for (i=1; i<=n; i++)???????x++;for (i=1; i<=n; i++)???? for (j=1; j<=n; j++)??????????x++; |
第一個for循環(huán)的時間復(fù)雜度為Ο(n),第二個for循環(huán)的時間復(fù)雜度為Ο(n2),則整個算法的時間復(fù)雜度為Ο(n+n2)=Ο(n2)。
常數(shù)時間
?
若對于一個算法,的上界與輸入大小無關(guān),則稱其具有常數(shù)時間,記作時間。一個例子是訪問數(shù)組中的單個元素,因?yàn)樵L問它只需要一條指令。但是,找到無序數(shù)組中的最小元素則不是,因?yàn)檫@需要遍歷所有元素來找出最小值。這是一項(xiàng)線性時間的操作,或稱時間。但如果預(yù)先知道元素的數(shù)量并假設(shè)數(shù)量保持不變,則該操作也可被稱為具有常數(shù)時間。
?
對數(shù)時間?
若算法的T(n)?=?O(log?n),則稱其具有對數(shù)時間
常見的具有對數(shù)時間的算法有二叉樹的相關(guān)操作和二分搜索。
對數(shù)時間的算法是非常有效的,因?yàn)槊吭黾右粋€輸入,其所需要的額外計(jì)算時間會變小。
遞歸地將字符串砍半并且輸出是這個類別函數(shù)的一個簡單例子。它需要O(log?n)的時間因?yàn)槊看屋敵鲋拔覀兌紝⒆址嘲搿?這意味著,如果我們想增加輸出的次數(shù),我們需要將字符串長度加倍。
線性時間
如果一個算法的時間復(fù)雜度為O(n),則稱這個算法具有線性時間,或O(n)時間。非正式地說,這意味著對于足夠大的輸入,運(yùn)行時間增加的大小與輸入成線性關(guān)系。例如,一個計(jì)算列表所有元素的和的程序,需要的時間與列表的長度成正比。
來自為知筆記(Wiz)
轉(zhuǎn)載于:https://www.cnblogs.com/hetan/p/5178554.html
總結(jié)
以上是生活随笔為你收集整理的python小白-day4递归和算法基础的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Leetcode题解(26)
- 下一篇: (王道408考研数据结构)第三章栈和队列