二分查找:
- 序列必须为有序序列
二分查找的几种变体:
- 查找 ==
- 查找第一个 >=
- 查找第一个 >
- …
C++
Python
def search(li, l, r, x):
"""
二分查找,查找等于x的index
:param li: 数组
:param l: 左指针
:param r: 右指针
:param x: 待查找的值
:return: index(找到)或 -1(未找到)
"""
while l <= r:
mid = int((l+r)/2)
if li[mid] == x:
return mid
elif li[mid] > x: # li[mid]左边找
r = mid - 1
else:
l = mid + 1
# l>r
return -1
def search_equa_bound(li, l, r, x):
"""
二分查找,升序序列中查找第一个大于等于x的index
:param li: 数组
:param l: 左指针
:param r: 右指针
:param x: 待查找的值
:return: index(找到)或 -1(未找到)
"""
while l < r:
mid = int((l + r) / 2)
if li[mid] >= x:
# li[mid]右边均>=x,则第一个大于等于x的可能在[l, mid]的闭区间
r = mid
else:
l = mid + 1
# l==r
if li[l] >= x:
return l
else:
return -1
def search_bound(li, l, r, x):
"""
二分查找,升序序列中查找第一个大于x的index
:param li: 数组
:param l: 左指针
:param r: 右指针
:param x: 待查找的值
:return: index(找到)或 -1(未找到)
"""
while l < r:
mid = int((l + r) / 2)
if li[mid] > x:
# li[mid]右边均>x,则第一个大于x的可能在[l, mid]的闭区间
r = mid
else:
l = mid + 1
# l==r
if li[l] > x:
return l
else:
return -1
li = [10, 20, 30, 40, 50, 60] # 升序
xs = [10, 60, 35]
for x in xs:
result = search(li, 0, len(li) - 1, x)
print(result) # [0, 5, -1]
xs = [5, 10, 25, 65]
for x in xs:
result = search_equa_bound(li, 0, len(li) - 1, x)
print(result) # [0, 0, 2, -1]
xs = [5, 10, 25, 65]
for x in xs:
result = search_bound(li, 0, len(li) - 1, x)
print(result) # [0, 1, 2, -1]