本篇主要是< <数据结构和算法-王争> >教程笔记和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