【演算法】Python有序列表的二分法查詢
阿新 • • 發佈:2018-11-22
二分法查詢的思路
先確定好列表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)