-
定義
- 二分查找又稱折半查找,是一種高效率的數據查找方法。其思想是按比例逐步縮小需要考慮的數據范圍,從而快速逼近需要查找的數據。該過程可以類比於我們中學時查字典的過程(假設 字典的索引被吃了),如果你要查詢一個字“破”,那么思考下你要怎么查詢?是不是首先需要根據“破”的拼音首字母“P”,找到在字典的大致位置(前半部分還是后半部分),顯然“P”位於26個英文字母的后半部分,因此下一步就是在這后半部分中再分為兩部分繼續確定,此時“P”位於前半部分,以此類推,直到找到“P”的位置(例如在字典的350-430頁)。然后次位的拼音“O”再按照這種方式,定位“PO”組合的位置。
-
查找過程(設順序表元素升序排列)
-
1)初始時,考慮的元素區間是整個順序表
-
2)取所考慮的元素范圍內位置居中的那個元素(中間項),比較該元素和檢索元素的關系,如果相等則檢索結束,返回True
-
3) 如果檢索元素大,則檢索范圍修改為中間項之后的半區間;如果檢索元素小,則檢索范圍修改為中間項之前的半區間
- 4)如果區間范圍內有數據就執行步驟2),否則檢索元素不在順序表中,返回False
-
實現
-
二分查找有遞歸實現和循環實現方式,如下:
def binary_search(search_list, search_element): """二分查找:基於遞歸,返回是否存在該元素""" s_len = len(search_list) if s_len > 0: mid_element = s_len // 2 # 中間元素恰好為所要查詢的元素 if search_list[mid_element] == search_element: return True # 所要查詢的元素位於原序列左側 elif search_list[mid_element] > search_element: return binary_search(search_list[:mid_element], search_element) # 所要查詢的元素位於原序列右側 else: return binary_search(search_list[mid_element+1:], search_element) return False if __name__ == "__main__": L1 = [1, 3, 5, 6, 12, 23, 34, 35, 43, 55, 65] print(binary_search(L1, 43)) print(binary_search(L1, 5)) print(binary_search(L1, 11)) print(binary_search(L1, 23))
def binary_search(search_list, search_element): """二分查找:基於循環,返回是否存在該元素""" s_len = len(search_list) # 利用索引值的改變,定位在原列表的查詢范圍 first_idx = 0 last_idx = s_len-1 # 當前面索引小於等於后面索引,執行查找;需要注意等號也成立 while first_idx <= last_idx: mid_idx = (first_idx + last_idx) // 2 if search_list[mid_idx] == search_element: return True elif search_list[mid_idx] > search_element: last_idx = mid_idx - 1 else: first_idx = mid_idx + 1 return False if __name__ == "__main__": L1 = [1, 3, 5, 6, 12, 23, 34, 35, 43, 55, 65] print(binary_search(L1, 43)) print(binary_search(L1, 5)) print(binary_search(L1, 11)) print(binary_search(L1, 23))
-
復雜度
- 最優時間復雜度:O(1)
- 最壞時間復雜度:O(logn)
-
優缺點
- 優點:查找速度快,比較次數少,平均性能好
- 缺點:要求待查表為有序表,且插入刪除困難
參考:數據結構與算法(python語言描述)裘宗燕
黑馬python數據結構與算法系列課程