二分法查找的思路
先确定好列表nums的左边 left, 右边right,
中间值mid 根据左边加上 右边减去左边的差除以2,即 left+ (right left) / 2。这种写法在Java中可以避免越界
将目标值target与nums[mid]进行比对,这时候有3种结果:
nums[middle] > target
nums[middle] < target
nums[middle] = target
以上3种情况前2种不断循环,直到满足第3种跳出循环。
# coding = utf-8
"""
在一个有序序列中找到指定元素,若找到返回其在数列中的位置,若没找到返回-1
"""
def binary_search(list1, k):
"""
二分(折半)查找
:param list1:
:param k:
:return:
"""
if list1 is None:
return -1
left = 0
right = len(list1) - 1
while left <= right:
mid = left + ((right - left) >> 1)
# 如果中间值 > 目标值,将右边界左移
if list1[mid] > k:
right = mid - 1
# 如果中间值 < 目标值,将左边界右移
elif list1[mid] < k:
left = list1[mid] + 1
else:
return mid
return -1
def binary_search2(list1, left, right, k):
"""
递归版二分查找
:param list1:
:param left:
:param right:
:param k:
:return:
"""
# 区间上只有一个数
if left == right:
return left if list1[left] == k else -1
# 划分区间
mid = (right + left) >> 1
# 如果中间值> 目标值,在左半边继续查找
if list1[mid] > k:
return binary_search2(list1, left, mid - 1, k)
# 如果中间值 < 目标值,在右半边继续查找
elif list1[mid] < k:
return binary_search2(list1, mid + 1, right, k)
else:
return mid
if __name__ == '__main__':
list1 = [1, 2, 3, 4, 8, 9, 10, 11]
k = 9
ret = binary_search(list1, k)
print(ret)
ret2 = binary_search2(list1, 0, len(list1) - 1, k)
print(ret2)