算法时间复杂度:θ(logn)
前提条件:当表中各项以升序出现时可以用这一算法。
(例如,若各项为数字,则按从最小到最大顺序排列;如果各项是单词,则可以按字典序或字母排列)。
这个算法比较要搜索的元素与表的中间项。然后此表就分成两个较小的长度相等的子表,或许其中有一个比另一个少一项。根据与中间项的比较结果,搜索将限于在两个子表中的一个进行。
例 要在表
1,2,3,5,6,7,8,10,12,13,15,16,18,19,20,22
中搜索19,第一步把有16个项的这个表分成各含8项的两个较小的表,即
1,2,3,5,6,7,8,10 12,13,15,16,18,19,20,22
然后比较19和头一个表的最大项。因为10<19,对19的搜索可以限于包含原表第9~16项的表中。下一步把含8项的
这个表分成含4项的小表,即
12,13,15,16 18,19,20,22
因为16<19(将19与第一个表的最大项比较),搜索限于这两个表的第二个,它包含原表的第13~16项。表
18,19,20,22再分成两个,即
18,19 20,22
因为19不大于两个表中第一个的最大项,这最大项也是19,搜索限于第一个表:18,19。这个表包含原表的第13
、14项。下一步,这个两项的表分成各含一项的两个表
18 19
因为18<19,搜索限于第二个表:这是只含原表第14项,即19的表。
现在搜索已经压缩到这一项上。与这一项比较,19定位为原表的第14项。
二分搜索算法的步骤:
要在表a1,a2,...,an中搜索整数x,其中a1<a2<...<an。
从比较x和序列的中间项am开始,其中m=└(n+1)/2┘(下取整函数,└x┘是不超过x的最大整数),
如果x>am,搜索可以限制在序列的下半段,即am+1,am+2,...,an。
如果x不大于am,搜索可限制在序列的上半段,即a1,a2,...,am。
现在搜索的范围于一个不超过┌n/2┐个元素的表。用同样的过程,比较x和这个短表的中间项,
然后把搜索限于短表的前半段或后半段,这样重复直到得到只含一项的表。然后判断这项是否就是x。
#include <stdio.h>
#define LEN 10
int a[LEN]={3,5,7,9,11,23,34,56,58,87};
int binary_search(int x)
{
int i=0; //i是搜索区间的左端点
int j=LEN-1; //j是搜索区间的右端点
int m=0,location=0;
while(i<j){
m=(i+j)/2;
if(x>a[m])
i=m+1;
else
j=m;
}
if(x==a[i])
location=i+1;
else
location=0;
printf("数%d在a[10]的%d位置\n",x,location);
}
int main(void)
{
int x=9;
binary_search(x);
return 0;
}