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