算法描述:
二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。
输入要查找的数字X ,每次比较列表中间元素m=(s+e)/2 奇数一般取前一个下标。X与m做比较是否相等
若比较元素 m < X 则S=m+1 m= (s+e)/2 寻找范围放到后面
继续比较新的m与X值是否相等 若m > X 则在 前s m 范围查找 e=m-1 m=(s+e)/2
如何判断结束呢,一种情况是找到了 m=x 则结束程序
一种没找到 e<=s 的情况代表没有找到
前提条件:
数组有序
复杂度:
首先在长度为n的表范围中查找,第一次循环在n/2中查找,第二次在n/2/2中查找, 依次循环。假设在第X次找到,那么 就是找2的X次方次,有2的X次方=n解出x为log2的n , 故时间复杂度为log2N。 由于辅助空间是常数级别的所以空间复杂度是O(1);
Python实现:
循环实现 :
#!/usr/bin/python
#-*-coding:utf-8-*-
numberlist = [1,3,5,7,9,11,15,17,19,21]
x = int(input("Input search number :"))
#strat 初始状态为0
s = 0
e = len(numberlist)-1
while s<=e:
print (s," ",m," ",e," ",numberlist[m],"--",x)
m = (s+e)//2
if numberlist[m] == x:
break
elif numberlist[m] < x:
s = m+1
elif numberlist[m] > x:
e = m-1
if s <= e:
print("found it !!")
else :
print("sorry didnot find !!")
递归实现:
def dichotomyFun(s,e,x):
m = (s+e)//2
print (s," ",m," ",e," ",numberlist[m],"--",x)
if s>=e :
return "sorry didnot find !!"
if numberlist[m] == x:
return "found it !!"
elif numberlist[m] < x:
s = m +1
dichotomyFun(s,e,x)
else :
e = m-1
dichotomyFun(s,e,x)
为了防止数值溢出,m = s+ (e - s)/2
旋转排序数组中查找数字:
例子:
【5,4,1,2,3】
查找4.
def secrch(numberlist,x):
l = len(numberlist)
if len == 0:
return -1
start = 0
end = len -1
while start <= end:
m = start +(end -start)//2
if numberlist[m]==x:
return m
else if numberlist[start] <= numberlist[m]:
if x < numberlist[m] && x > numberlist[start]:
start =m -1
else :
end =m+1
else if numberlist[m] <= numberlist[end]:
if x>numberlist[m] && x<=numberlist[end]:
start = m+1
else :
end=m-1
return -1