手把手教你用Python实现查找算法
導(dǎo)讀:在復(fù)雜的數(shù)據(jù)結(jié)構(gòu)中高效地查找數(shù)據(jù)是其非常重要的功能之一。最簡單的方法是在每個數(shù)據(jù)點中查找所需數(shù)據(jù),效率并不高。因此隨著數(shù)據(jù)規(guī)模的增加,我們需要設(shè)計更復(fù)雜的算法來查找數(shù)據(jù)。
作者:伊姆蘭·艾哈邁德(Imran Ahmad)
來源:大數(shù)據(jù)DT(ID:hzdashuju)
本文介紹以下查找算法:
線性查找(Linear Search)
二分查找(Binary Search)
插值查找(Interpolation Search)
我們詳細了解一下它們各自的情況。
01?線性查找
查找數(shù)據(jù)的最簡單策略就是線性查找,它簡單地遍歷每個元素以尋找目標(biāo),訪問每個數(shù)據(jù)點從而查找匹配項,找到匹配項后,返回結(jié)果,算法退出循環(huán),否則,算法將繼續(xù)查找,直到到達數(shù)據(jù)末尾。線性查找的明顯缺點是,由于固有的窮舉搜索,它非常慢。它的優(yōu)點是無須像其他算法那樣,需要數(shù)據(jù)排好序。
我們看一下線性查找的代碼:
def?LinearSearch(list,?item):index?=?0found?=?False#?Match?the?value?with?each?data?element???????while?index?<?len(list)?and?found?is?False:if?list[index]?==?item:found?=?Trueelse:index?=?index?+?1return?found現(xiàn)在,看一下代碼的輸出(見圖3-15)。
list?=?[12,?33,?11,?99,?22,?55,?90] print(LinearSearch(list,?12)) print(LinearSearch(list,?91))▲圖 3-15
需要注意的是,如果能成功找到數(shù)據(jù),運行LinearSearch函數(shù)會返回True。
線性查找的性能:如上所述,線性查找是一種執(zhí)行窮舉搜索的簡單算法,其最壞時間復(fù)雜度是O(N)。
02 二分查找
二分查找算法的前提條件是數(shù)據(jù)有序。算法反復(fù)地將當(dāng)前列表分成兩部分,跟蹤最低和最高的兩個索引,直到找到它要找的值為止:
def?BinarySearch(list,?item):first?=?0last?=?len(list)-1found?=?Falsewhile?first<=last?and?not?found:midpoint?=?(first?+?last)//2if?list[midpoint]?==?item:found?=?Trueelse:if?item?<?list[midpoint]:last?=?midpoint-1else:first?=?midpoint+1return?found輸出結(jié)果如圖3-16所示。
list?=?[12,?33,?11,?99,?22,?55,?90] sorted_list?=?BubbleSort(list) print(BinarySearch(list,?12)) print(BinarySearch(list,?91))▲圖 3-16
請注意,如果在輸入列表中找到了值,調(diào)用BinarySearch函數(shù)將返回True。
二分查找的性能:二分查找之所以如此命名,是因為在每次迭代中,算法都會將數(shù)據(jù)分成兩部分。如果數(shù)據(jù)有N項,則它最多需要O(log N)步來完成迭代,這意味著算法的運行時間為O(log N)。
03 插值查找
二分查找的基本邏輯是關(guān)注數(shù)據(jù)的中間部分。插值查找更加復(fù)雜,它使用目標(biāo)值來估計元素在有序數(shù)組中的大概位置。
讓我們試著用一個例子來理解它:假設(shè)我們想在一本英文詞典中搜索一個單詞,比如單詞river,我們將利用這些信息進行插值,并開始查找以字母r開頭的單詞,而不是翻到字典的中間開始查找。一個更通用的插值查找程序如下所示:
def?IntPolsearch(list,x?):idx0?=?0idxn?=?(len(list)?-?1)found?=?Falsewhile?idx0?<=?idxn?and?x?>=?list[idx0]?and?x?<=?list[idxn]:#?Find?the?mid?pointmid?=?idx0?+int(((float(idxn?-?idx0)/(?list[idxn]?-?list[idx0]))?*?(?x?-?list[idx0])))#?Compare?the?value?at?mid?point?with?search?value?if?list[mid]?==?x:found?=?Truereturn?foundif?list[mid]?<?x:idx0?=?mid?+?1return?found輸出結(jié)果如圖3-17所示。
list?=?[12,?33,?11,?99,?22,?55,?90] sorted_list?=?BubbleSort(list) print(IntPolsearch(list,?12)) print(IntPolsearch(list,91))▲圖 3-17
請注意,在使用IntPolsearch函數(shù)之前,首先需要使用排序算法對數(shù)組進行排序。
插值查找的性能:如果數(shù)據(jù)分布不均勻,則插值查找算法的性能會很差,該算法的最壞時間復(fù)雜度是O(N)。如果數(shù)據(jù)分布得相當(dāng)均勻,則最佳時間復(fù)雜度是O(log(log N))。
關(guān)于作者:伊姆蘭·艾哈邁德(Imran Ahmad) 是一名經(jīng)過認證的谷歌講師,多年來一直在谷歌和學(xué)習(xí)樹(Learning Tree)任教,主要教授Python、機器學(xué)習(xí)、算法、大數(shù)據(jù)和深度學(xué)習(xí)。他在攻讀博士學(xué)位期間基于線性規(guī)劃方法提出了名為ATSRA的新算法,用于云計算環(huán)境中資源的優(yōu)化分配。近4年來,他一直在加拿大聯(lián)邦政府的高級分析實驗室參與一個備受關(guān)注的機器學(xué)習(xí)項目。
本文摘編自《程序員必會的40種算法》,經(jīng)出版方授權(quán)發(fā)布。
延伸閱讀《程序員必會的40種算法》
推薦語:本書致力于利用算法求解實際問題,幫助初學(xué)者理解算法背后的邏輯和數(shù)學(xué)知識。本書內(nèi)容豐富,涉及算法基礎(chǔ)、設(shè)計技術(shù)、分析方法、排序算法、查找算法、圖算法、線性規(guī)劃算法、機器學(xué)習(xí)算法、推薦算法、數(shù)據(jù)算法、密碼算法和并行算法等內(nèi)容,重點講述如何使用Python進行算法實現(xiàn)和算法性能的比較與分析。
刷刷視頻👇
干貨直達👇
9種深度學(xué)習(xí)算法簡介
詳解數(shù)據(jù)治理相關(guān)的7個術(shù)語和名詞
簡析Kubernetes八大重要特性
盤點13種流行的數(shù)據(jù)處理工具
更多精彩👇
在公眾號對話框輸入以下關(guān)鍵詞
查看更多優(yōu)質(zhì)內(nèi)容!
讀書?|?書單?|?干貨?|?講明白?|?神操作?|?手把手
大數(shù)據(jù)?|?云計算?|?數(shù)據(jù)庫?|?Python?|?爬蟲?|?可視化
AI?|?人工智能?|?機器學(xué)習(xí)?|?深度學(xué)習(xí)?|?NLP
5G?|?中臺?|?用戶畫像?|?數(shù)學(xué)?|?算法?|?數(shù)字孿生
據(jù)統(tǒng)計,99%的大咖都關(guān)注了這個公眾號
👇
總結(jié)
以上是生活随笔為你收集整理的手把手教你用Python实现查找算法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 做决定前别拍脑袋:两个成功案例看懂A/B
- 下一篇: 20 行 Python 代码说清量子霸权