1、 二分查找法
所谓的二分查找法,就是对于一个有序列表,通过每次取中间值来判断是否为所要查找的数值。比如我们聚会时玩的猜数字游戏,0到100之间猜一个数值,有两种方法:一是我们可以一个一个的去猜,但是这样比较耗时,效率低;其次就是二分法,第一次取中间值50,对方会告诉你高了或者低了,若高了,继续取0到49的中间值25,若此时低了,将取值范围设定为26到49之间,依次下去,便可猜出真正的数值。
2、注意:
A. 使用二分法时,必须为有序列表,若为无序列表则需先排序;
B. 普通逐个查询的时间复杂度为O(n),使用二分法进行查找的时间复杂度为O(log n),当搜索的元素越多时,O(log n)比O(n)快得越多;
C. 时间复杂度一般按最坏情况下的运行去衡量;
D. 算法的速度指的并非时间,而是指操作数的增速,即随着输入的增加,其运行时间将以什么样的速度增加;
3. Python代码实现
import time
def wrapper(func):
def counttime(*args):
start = time.time()
ret = func(*args)
end = time.time()
time_total = end - start
return ret, time_total
return counttime
@wrapper
def search_num(aim_list, num):
"""
二分法查找数值所在索引位置
:param aim_list: 有序列表
:param num: 查找目标数值
:return: 目标数值所在索引位置
"""
start = 0
end = len(aim_list) - 1
while start <= end:
mid = (start + end) // 2
mid_num = aim_list[mid]
if mid_num == num:
return mid
elif mid_num < num:
start = mid + 1
else:
end = mid - 1
return None
@wrapper
def find_num(list, item):
"""
普通挨个查找数据所在位置
:param list: 有序列表
:param item: 查找目标数值
:return: 目标数值所在索引位置
"""
for i in list:
if i == item:
return list.index(i)
list = [i for i in range(1,10001)]
num = 9999
ind1, time1= search_num(list, num)
ind2, time2= find_num(list, num)
print("二分法查找%d的索引位置为%d,耗时%f" % (num, ind1, time1))
print("普通查找%d的索引位置为%d,耗时%f" % (num, ind2, time2))
结果为: