在计算机科学中,折半搜索是一种在有序数组中查找某一特定元素的搜索算法。搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。这种搜索算法每一次比较都使搜索范围缩小一半。以上是来自wiki的解释。接下来看看Python的对这个算法的实现:
一、自己手动写:
def binary_search(data,find,lo=0,hi=None):
hi = hi if hi is not None else len(data)
while lo < hi:
mid = (lo+hi)//2
midval = data[mid]
if midval < find:
lo = mid +1
elif midval > find:
hi = mid
else:
return mid
return -1
if __name__ =="__main__":
#init a sorted list
data =[]
for i in range(0,100):
data.append(i)
#set a number we want to search
find = 65
index = binary_search(data,find)
print index
执行结果当然返回的是65。算法简要分析:
- O( n log n) 初始化创建列表
- O( log n) 用于查找
- O( n )插入或者删除(有可能是O(1)或者O(log n))
除了自己手动写以上的代码,你还可以使用python模块bisect.
from bisect import bisectfrom random import randrange
# Generate a sorted list of 100 thousand random numbers.
print 'Generating sorted random list...'
list = []
for i in range (0,100000):
list.append(randrange(10000000))
# This does all the work.
list.sort()
insert_point = bisect (list, number)
#insert_point返回的就是你要插入的位置
(注意一下例子返回的不是你要搜索的那个值在list的位置,而是要插入的位置),如果要返回搜索位置,可以如下:
from bisect import bisect_left
def binary_search_2(data,find,lo=0,hi=None):
hi = hi if hi is not None else len(data)
pos = bisect_left(data,find,lo,hi)
return (pos if pos != hi and data[pos] == find else -1)
if __name__ =="__main__":
#init a sorted list
data =[]
for i in range(0,100):
data.append(i)
#set a number we want to search
find = 165
index = binary_search_2(data,find)
print index
该例子返回为-1,就是没有搜索到的意思。