之前分析了好多排序算法,可難理解了呢!!(泣不成聲)
這次我要把二分查找總結一下,這個算法不算難度特別大,歡迎大家參考借鑒
我不喜歡太官方的定義,太晦澀的語言,讓人看了就頭暈。我希望加入我自己的理解,能幫助大家更好的理解算法的原理
同時也歡迎大家批評指正
二分查找:
我們手里有一個長度為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 以上就是兩種實現二分查找的方法。
因為思想相同,他們的時間復雜度是一樣的。
但是遞歸的方式,每次都要開新的列表,實際上空間復雜度會更大一些。
謝謝你的觀賞~歡迎大家批評指正!