python中兩種方法實現二分法查找,細致分析二分法查找算法


之前分析了好多排序算法,可難理解了呢!!(泣不成聲)
這次我要把二分查找總結一下,這個算法不算難度特別大,歡迎大家參考借鑒

我不喜歡太官方的定義,太晦澀的語言,讓人看了就頭暈。我希望加入我自己的理解,能幫助大家更好的理解算法的原理
同時也歡迎大家批評指正

二分查找:
我們手里有一個長度為n的正序數列,當我們想查找一個數 x是否在這個數列當中的時候
1 取數列正中間的數mid,
如果mid和x相等,則找到結果,查找成功 返回True
如果mid比x大,則x應該在mid的左側,我們把mid左側當作一個新的數列li
如果mid比x小,則x應該在mid的右側,我們把mid右側當作一個新的數列li
2 對於新的數列li 進行1的查找工作

3 一直重復上面查找,生成新的數列li為空的時候則 數列當中沒有數x 返回False

時間復雜度:最優O(1) 我們取第一次中間數mid 找到了 這種概率很低
最壞O(log n) 假設n個數的數列,每次把數列分成兩半,n除以多少次2 等於1 呢? log n次


首先我們用遞歸的方式實現二分查找算法:
 1 #遞歸實現二分查找 li是列表 item是要查找的元素
 2 def merge_search( li ,item ):  3     #傳來的列表每次都是新生成的,如果發現里面沒有元素,則是查找到盡頭都沒找到
 4     if not li :  5         return False  6 
 7     mid = len(li)//2   #mid記錄li的中間位置
 8     #檢查一下 如果中間這個數就是要找的元素 返回真
 9     if li[mid] == item : 10         return True 11     # 如果mid比item大,說明item可能會出現在mid左邊,對左邊再查找
12     elif li[mid]> item : 13         return merge_search( li[:mid] ,item ) 14     # mid 比item小,說明item有可能在mid右邊,對右邊再查找
15     else : 16         return merge_search( li[mid+1:] , item ) 17 
18 if __name__ == '__main__': 19     li = [1,2,3,4,5,6,7] 20     print( merge_search(li , 0) )   #False
21     print( merge_search(li , 1) )   #True

 

 

下面我們嘗試用while循環去實現二分查找:

 1 def merge_search( li , item ):  2     #獲取li的開始 結束
 3     start = 0  4     end = len(li)-1
 5 
 6     #只要start和end 還沒錯開 就一直找
 7     while start <= end :  8         #通過計算獲取當前查找范圍的中間位置
 9         mid = (start + end)//2
10         #如果中間數就是item則返回True
11         if li[mid] == item : 12             return True 13         #如果mid比item大,說明item可能會出現在mid左邊,對左邊再查找
14         elif li[mid]> item : 15             end = mid - 1
16         # mid 比item小,說明item有可能在mid右邊,對右邊再查找
17         else : 18             start = mid + 1
19     #跳出循環說明沒找到 返回錯誤
20     return False 21 
22 if __name__ == '__main__': 23     li = [1,2,3,4,5,6,7,8] 24     print( merge_search(li , 8) ) #True
25     print( merge_search(li , 0) ) #False

 

 

 

OK 以上就是兩種實現二分查找的方法。

因為思想相同,他們的時間復雜度是一樣的。

但是遞歸的方式,每次都要開新的列表,實際上空間復雜度會更大一些。



謝謝你的觀賞~歡迎大家批評指正!



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM