




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
第Python查找算法如何實(shí)現(xiàn)print(pos)
通過前面對二分算法流程的分析,可知二分查找的子問題和原始問題是同一個邏輯,所以可以使用遞歸實(shí)現(xiàn):
遞歸實(shí)現(xiàn)二分查找
defbinary_find_dg(nums,key,l_idx,r_ldx):
ifl_idxr_ldx:
#出口一:沒有查找到給定關(guān)鍵字
return-1
#計算出中間位置
mid_pos=(r_ldx+l_idx)//2
#計算中間位置的值
mid_val=nums[mid_pos]
#與關(guān)鍵字比較
ifmid_val==key:
#出口二:比較相等,有此關(guān)鍵字,返回關(guān)鍵字所在位置
returnmid_pos
elifmid_valkey:
#說明查找范圍應(yīng)該縮少在原數(shù)的左邊
r_ldx=mid_pos-1
else:
l_idx=mid_pos+1
returnbinary_find_dg(nums,key,l_idx,r_ldx)
測試二分查找
if__name__==__main__:
nums=[1,3,4,5,8,10,12]
key=8
pos=binary_find_dg(nums,key,0,len(nums)-1)
print(pos)
二分查找性能分析:
二分查找的過程用樹形結(jié)構(gòu)描述會更直觀,當(dāng)搜索完畢后,繪制出來樹結(jié)構(gòu)是一棵二叉樹。
1.如上述代碼執(zhí)行過程中,先找到數(shù)列中的中間數(shù)字5,然后以5為根節(jié)點(diǎn)構(gòu)建唯一結(jié)點(diǎn)樹。
2.5和關(guān)鍵字8比較后,再在以數(shù)字5為分界線的右邊數(shù)列中找到中間數(shù)字10,樹形結(jié)構(gòu)會變成下圖所示。
3.10和關(guān)鍵字8比較后,再在10的左邊查找。
查找到8后,意味著二分查找已經(jīng)找到結(jié)果,只需要3次就能查找到最終結(jié)果。
從二叉樹的結(jié)構(gòu)上可以直觀得到結(jié)論:二分查找關(guān)鍵字的次數(shù)由關(guān)鍵字在二叉樹結(jié)構(gòu)中的深度決定。
4.上述是查找給定的數(shù)字8,為了能查找到數(shù)列中的任意一個數(shù)字,最終完整的樹結(jié)構(gòu)應(yīng)該如下圖所示。
很明顯,樹結(jié)構(gòu)是標(biāo)準(zhǔn)的二叉樹。從樹結(jié)構(gòu)上可以看出,無論查找任何數(shù)字,最小是1次,如查找數(shù)字5,最多也只需要3次,比線性查找要快很多。
根據(jù)二叉樹的特性,結(jié)點(diǎn)個數(shù)為n的樹的深度為h=log2(n+1),所以二分查找算法的大O表示的時間復(fù)雜度為O(logn),是對數(shù)級別的時間度。
當(dāng)對長度為1000的數(shù)列進(jìn)行二分查找時,所需次數(shù)最多只要10次,二分查找算法的效率顯然是高效的。
然而,二分查找算法在實(shí)行之前需要對數(shù)列進(jìn)行排序,因此前面所述的時間復(fù)雜度并未包含排序所需的時間。所以,二分查找一般適合數(shù)字變化穩(wěn)定的有序數(shù)列。
3.插值查找
插值查找本質(zhì)是二分查找,插值查找對二分查找算法中查找中間位置的計算邏輯進(jìn)行了改進(jìn)。
原生二分查找算法中計算中間位置的邏輯:中間位置等于左指針位置加上右指針位置然后除以2。
#計算中間位置
mid_pos=(r_ldx+l_idx)//2
插值算法計算中間位置邏輯如下所示:
key為要查找的關(guān)鍵字!!
#插值算法中計算中間位置
mid_pos=l_idx+(key-nums[l_idx])//(nums[r_idx]-nums[l_idx])*(r_idx-l_idx)
編碼實(shí)現(xiàn)插值查找:
#插值查找基于二分法,只是mid計算方法不同
defbinary_search(nums,key):
l_idx=0
r_idx=len(nums)-1
old_mid=-1
mid_pos=None
whilel_idxr_idxandnums[0]=keyandnums[r_idx]=keyandold_mid!=mid_pos:
#中間位置計算
mid_pos=l_idx+(key-nums[l_idx])//(nums[r_idx]-nums[l_idx])*(r_idx-l_idx)
old_mid=mid_pos
ifnums[mid_pos]==key:
returnindexis{},targetvalueis{}.format(mid_pos,nums[mid_pos])
#此時目標(biāo)值在中間值右邊,更新左邊界位置
elifnums[mid_pos]key:
l_idx=mid_pos+1
#此時目標(biāo)值在中間值左邊,更新右邊界位置
elifnums[mid_pos]key:
r_idx=mid_pos-1
returnNotfind
li=[1,3,4,5,8,10,12]
print(binary_search(li,6))
插值算法的中間位置計算時,對中間位置的計算有可能多次計算的結(jié)果是一樣的,此時可以認(rèn)為查找失敗。
插值算法的性能介于線性查找和二分查找之間。
如果序列具有較大數(shù)量的均勻分布的數(shù)字,插值查找算法的平均執(zhí)行效率要比二分查找好得多。如果數(shù)據(jù)在數(shù)列中分布不均勻,插值算法并不是最優(yōu)選擇。
4.分塊查找
分塊查找類似于數(shù)據(jù)庫中的索引查詢,所以分塊查找也稱為索引查找。其算法的核心還是線性查找。
現(xiàn)有原始數(shù)列nums=[5,1,9,11,23,16,12,18,24,32,29,25],需要查找關(guān)鍵字11是否存在。
第1步:使用分塊查找之前,先要對原始數(shù)列按區(qū)域分成多個塊。至于分成多少塊,可根據(jù)實(shí)際情況自行定義。分塊時有一個要求,前一個塊中的最大值必須小于后一個塊的最小值。
塊內(nèi)部無序,但要保持整個數(shù)列按塊有序。
分塊查找要求原始數(shù)列從整體上具有升序或降序趨勢,如果數(shù)列的分布不具有趨向性,如果仍然想使用分塊查找,則需要進(jìn)行分塊有序調(diào)整。
第2步:根據(jù)分塊信息,建立索引表。索引表至少應(yīng)該有2個字段,每一塊中的最大值數(shù)字以及每一塊的起始地址。顯然索引表中的數(shù)字是有序的。
第3步:查找給定關(guān)鍵字時,先查找索引表,查詢關(guān)鍵字應(yīng)該在那個塊中。如查詢關(guān)鍵字29,可知應(yīng)該在第三塊中,然后根據(jù)索引表中所提供的第三塊的地址信息,再進(jìn)入第三塊數(shù)列,按線性匹配算法查找29具體位置。
編碼實(shí)現(xiàn)分塊查找:
先編碼實(shí)現(xiàn)根據(jù)分塊數(shù)量、創(chuàng)建索引表,這里使用二維列表保存儲索引表中的信息。
分塊:建立索引表
nums原始數(shù)列
blocks塊大小
defcreate_index_table(nums,blocks):
#索引表使用列表保存
index_table=[]
#每一塊的數(shù)量
n=len(nums)//blocks
foriinrange(0,len(nums),n):
#索引表中的每一行記錄
tmp_lst=[]
#最大值
tmp_lst.append(max(nums[i:i+n-1]))
#起始地址
tmp_lst.append(i)
#終止地址
tmp_lst.append(i+n-1)
#添加到索引表中
index_table.append(tmp_lst)
returnindex_table
nums=[5,1,9,11,23,16,12,18,24,32,29,25]
it=create_index_table(nums,3)
print(it)
輸出結(jié)果:
[[11,0,3],[23,4,7],[32,8,11]]
代碼執(zhí)行后,輸出結(jié)果和分析的結(jié)果一樣。
以上代碼僅對整體趨勢有序的數(shù)列進(jìn)行分塊。如果整體沒有向有序趨勢發(fā)展,則需要提供適當(dāng)?shù)膲K排序計劃,有興趣的人可以自行完成。
如上代碼僅為說明分塊查找算法。
分塊查找的完整代碼:
分塊:建立索引表
nums原始數(shù)列
blocks塊大小
defcreate_index_table(nums,blocks):
#索引表使用列表保存
index_table=[]
#每一塊的數(shù)量
n=len(nums)//blocks
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 轉(zhuǎn)讓機(jī)器技術(shù)合同協(xié)議
- 水桶購買協(xié)議書
- 期貨減產(chǎn)協(xié)議書
- 《血液輸注原理與應(yīng)用》課件
- 三方出資合伙合同
- 遮光補(bǔ)償協(xié)議書合同協(xié)議
- 通風(fēng)空調(diào)工程合同協(xié)議
- 諒解協(xié)議書格式模板
- 漏水修補(bǔ)協(xié)議書
- 服裝設(shè)計定制服務(wù)合同
- 拋石專項(xiàng)施工方案
- 電力增材再造技術(shù)的創(chuàng)新與發(fā)展
- 話劇導(dǎo)演合同協(xié)議
- 客服代理合同協(xié)議
- 躁狂癥病人的護(hù)理
- 2025中國汽車出海潛在市場研究:澳大利亞篇-2025-03-市場解讀
- 高中女生預(yù)防性侵教育
- 醫(yī)院建設(shè)項(xiàng)目醫(yī)療專項(xiàng)工程醫(yī)用氣體工程技術(shù)參數(shù)及要求
- 合同歸檔培訓(xùn)課件
- 2025年西城二模化學(xué)試題及答案
- 《詞根詞綴記詞法》課件
評論
0/150
提交評論