本篇主要是< <數據結構和算法-王爭> >教程筆記和python實現 python
原理: 在一個有序數組中, 不斷比較中間位置的數和目標數的大小, 若是中間位置數比目標數大, 則再用一樣辦法比較前半部分, 不然比較後半部分. 若是沒有找到目標數的位置, 返回None, 不然返回該數的位置. 由於是不斷把數組分爲一半一半的找, 因此時間複雜度是O(logn)
.算法
時間複雜度: O(logn)數組
注: 要注意邊界狀況數據結構
# coding:utf-8 def binary_search(nums, value): low = 0 high = len(nums) - 1 # 注意是 <= while low <= high: mid = int((low + high) / 2) mid_value = nums[mid] # 注意 low 和 high 的取值, 防止發生死循環. 好比low=3, high=3 if mid_value < value: low = mid + 1 elif mid_value > value: high = mid - 1 else: return mid return -1 if __name__ == "__main__": nums = [1, 2, 3, 4, 5] print(binary_search(nums, 5))
注意點:數據結構和算法
mid = int((low + high) / 2)
可能發生整數溢出, 能夠優化改成mid = low + int((high-low)/2) # 或 low + int((high - low) >> 1) # 位運算
缺點:優化
通常狀況下能用二分查找解決的問題也可使用二叉查找樹和散列表來解決, 可是二分查找適合如下問題code
如下狀況容許出現重複元素排序
# coding:utf-8 """ 查找數組中第一個=給定值的元素, 返回索引位置 """ def binary_search(nums, value): low = 0 high = len(nums) - 1 while low <= high: mid = low + ((high - low) >> 1) mid_value = nums[mid] if mid_value < value: low = mid + 1 elif mid_value > value: high = mid - 1 else: if mid == 0 or nums[mid - 1] != value: return mid else: high = mid - 1 return -1 if __name__ == "__main__": nums = [1, 3, 4, 5, 6, 8, 8, 8, 11, 18] print(binary_search(nums, 8))
def binary_search_2(nums, value): """ 查找數組中最後一個等於給定值的元素, 返回索引位置 """ low = 0 high = len(nums) - 1 last_pos = high while low <= high: mid = low + ((high - low) >> 1) mid_value = nums[mid] if mid_value < value: low = mid + 1 elif mid_value > value: high = mid - 1 else: # 若是mid==最後一位, 那麼是第一個元素確定是要找的值 if mid == last_pos or nums[mid + 1] != value: return mid else: # 要找的值確定在mid+1和high之間 low = mid + 1 return -1
def binary_search_3(nums, value): """ 查找數組中第一個 >= 給定值的元素, 返回索引位置 """ low = 0 high = len(nums) - 1 while low <= high: mid = low + ((high - low) >> 1) mid_value = nums[mid] if mid_value >= value: if mid == 0 or nums[mid - 1] < value: return mid else: high = mid - 1 else: low = mid + 1 return -1
def binary_search_4(nums, value): """ 查找數組中最後一個 <= 給定值的元素, 返回索引位置 """ low = 0 high = len(nums) - 1 last_pos = high while low <= high: mid = low + ((high - low) >> 1) mid_value = nums[mid] if mid_value > value: high = mid - 1 else: if mid == last_pos or nums[mid + 1] > value: return mid else: low = mid + 1 return -1