查找有线性查找、二分查找、通过搜索树查找
1.二分查找是对有序表查找方式。
二分查找(名折半查找)的查找过程:先确定待查找记录所在的范围(区间),然后逐步缩小范围直到 找到或 找不到 该记录为止。
二分经常让手写,注意边界。
时间复杂度为 :O(log2n),log以2为底 n 的对数,可以简写成 O(log n)。
空间复杂度:递归形式复杂度O(n),递归一次要开辟一个空间。非递归形式复杂度O(1)。
方法一:使用普通方法实现(比递归效率高) , recursive /rɪ'kɜːsɪv/ 递归的,循环的
def binary_search(sorted_array, val):
if not sorted_array:
return -1
beg = 0 # 指向开头
end = len(sorted_array) - 1 # 指向结尾
while beg <= end:
mid = int((beg + end) / 2) # 为了屏蔽Python2/3差异,使用类型强转。
if sorted_array[mid] == val:
return mid
elif sorted_array[mid] > val:
end = mid - 1
else:
beg = mid + 1
return -1
def test_binary_search():
array = [1, 2, 3, 4, 5, 6, 9, 10, 13, 17]
print(array)
print(binary_search(array, 17))
test_binary_search()
代码二:使用递归方法实现
def binary_search_recursive(sorted_array, beg, end, val):
'''
递归方式实现二分,注意递归出口
'''
if beg > end:
return -1
mid = int((beg +end) / 2) # 为了屏蔽Python2/3差异,使用类型强转。
if sorted_array[mid] == val:
return mid
elif sorted_array[mid] > val:
return binary_search_recursive(sorted_array, beg, mid -1, val)
else:
return binary_search_recursive(sorted_array, mid + 1, end, val)
def test_binary_search_recursive():
array = [1, 2, 3, 4, 5, 6, 9, 10, 13, 17]
print(array)
print(binary_search_recursive(array, 0, 9, 17))
test_binary_search_recursive()
2.对无序表实现二分查找
(注意:我这里是实现,说明对无序表不能直接进行二分查找)
二分查找又称折半查找
必须采用顺序存储结构
必须按关键字大小有序排列(如果是一个乱序的列表,必须先进行排序,才能用二分查找)
alist = [0, 1, 10, 88, 19, 9, 1]
def binary_search(arr, start, end, hkey):
if start > end:
return -1
mid = int((start + end) / 2) # 为了屏蔽Python2/3差异,使用类型强转。
if arr[mid] > hkey:
return binary_search(arr, start, mid - 1, hkey)
if arr[mid] < hkey:
return binary_search(arr, mid + 1, end, hkey)
return mid
alist = sorted(alist)
print(alist)
print(binary_search(alist, 0, 6, 9)) # 返回已经排好序列表中9元素的位置
注意:如果函数的参数列表中有指向数组开始和结尾的两个指针参数,可以使用递归实现二分查找;如果函数只有列表和目标值两个参数是无法使用递归实现的,因为使用递归肯定切片生成新的列表目标值的下标已经改变。