说明:二分查找的方式适用于一个有序数组(列表),因为每次查找的数据都会在一个范围内取中间位置的数据比较,如果没有找到则会在另外一个区间,重复做这样的操作。
举个栗子,加入在1-100的数组中,任意给你一个数字,请问它是多少?加入这个数是35。
思路是这样的,
第一步,0+100/2=50,就会用50来判断,结果是比50小。
第二步,0+50/2=25,用25来判断,结果是比25大。
第三步,25+50/2=37(如果结果不是偶数,自动向下取整),结果比37小。
第四步,25+37/2=31,结果又比31大。
第五步,31+37/2=34,结果比34大。
第六步,37+34/2=35,找到目标。
在上述描述中,如果用代码来实现,也就是需要循环6次就找到了结果。而实际上,最糟糕的时候,就是当目标为1或者100的时候,此时也仅仅只需要8步就可以完成。实际上满足2的n次方,2的8次方等于128,2的7次方64。
代码实现:
1,程序执行过程
def binary_search(list_item,item):
# 列表的起始索引
low = 0
# 列表的最终下标
high = len(list_item)
# 程序会一直进行下去,直到二者相等
while low < high:
# 第一次需要查找的索引
mid = int((low + high)/2)
# 在列表中查找到索引对应的值
guess = list_item[mid]
# 如果我们索引中的数字等于需要查找的目标,则程序结束,返回对应的索引
if guess == item:
return mid
# 如果列表中对应的数字大于我们需要查找的目标,
# 此时就把最大索引设置为上一次查找的索引减去1(因为上一次的索引已经用作判断)
if guess > item:
high = mid
# 同理,当我们需要查找的对象大于我们索引对应的值,此时,就需要将low设置为mid+1
else:
low = mid + 1
#程序没有指定元素,就返回空。
return None
if __name__ == "__main__":
list_item = [1,3,5,7,9,23,43,57,58,60,76,89,100]
index = binary_search(list_item,89)
print ('查找的索引是{0},对应的数字是{1}'.format(index,list_item[index]))
运行的结果是:
查找的索引是11,对应的数字是89
2,使用binary_search()方法
这个方法接受一个有序数组和一个元素。
示例代码:
result = binary_search([1,3,5,7,9,23,43,57,58,60,76,89,100],43)
print ('查找结果是:{}'.format(result))
运行的结果是:
查找结果是:6