二分搜索的思想是把数据项集合分成两部分,确定搜索关键字属于哪一个部分,然后集中处理那一部分。划分数据项的一种合理方式是保持数据项有序,然后在有序数组中使用下标来界定所要处理的那一部分数组。
下面给出实现:
#include <stdio.h>
int* search( int a[], int l, int r,int key);
int main( int argc, char* argv[] )
{
int a[] ={0,1,2,3,4,5,6,7,8,9,10};
if( argc!= 2 )
{
printf("error \n");
return-1;
}
int*position = NULL;
int key =atoi(argv[1]);
position= search( a,0,sizeof(a)/sizeof(a[0])-1,key);
if(position == NULL )
{
printf("Ican not find:%d\n",key);
}
else
{
printf("Ifind:%d,in position:%d\n",key,position-a);
}
return 0;
}
int* search( int a[],int l,int r ,int key)
{
int mid =(l+r)/2;
if(a[mid] == key )
{
returna+mid;
}
if(l>= r )
{
returnNULL;
}
if(a[mid] > key )
returnsearch(a,l,mid,key);
else
returnsearch(a,mid+1,r,key);
}
对于二分搜索还有一种改进方法称为插值搜索,其思想和二分搜索一样只是对于计算mid的值时采用另一种方法:
mid = l +(key-a[l])*((r-l)/(a[r]-a[l]))
这个公式是这样得出的:
mid=(l+r)/2=l+1/2(r-l)然后用(key-a[l])(a[r]-a[l])替换1/2。二分搜索的比较次数是lgn+1二插值搜索比较次数是lglgN+1。这个函数增长缓慢,可以看做常量。如果N=10亿lglgN<5。对于分布随机的关键字插值搜索的性能更好。