今天我们来看看二分法,它建立在已经排序好的线性表基础上,我们假设线性表进行了升序的排列,将要查找的元素与线性表中间的元素进行比较,如果元素比中间的大,
那么,再在后半部分进行同样方法的查找;以此。。。直到待查找的线性表只剩一个元素。
这是一种比较高效的查找方法了,它的时间复杂度为O(logN) 底为2,N代表线性表长度,也就是说,如果线性表长为8,那么最多只需要3次比较(2的3次方为8),就可以得到结果;
通过本文对二分法的实现,我们来回顾一下,C语言中的回调、递归;
1、回调
examp1. 未使用回调:
/*找得到返回位置,没有返回-1*/
int binary_search(int a[], int len, int e)
{
int start = 0, end = len -1;
int mid = start+(end-start)/2;
int cond = 0;
for(; start < end; )
{
if((cond = (a[mid]-e)) == 0) return mid;
else if(cond > 0)
{
end = mid;
}
else
{
start = mid+1;
}
mid = start + (end-start)/2;
}
return -1;
}
example2. 使用了回调:
int binary_search(int a[], int len, int e, int (*comp)(int a, int e))
{
int start = 0, end = len -1;
int mid = start+(end-start)/2;
int cond;
for(; start < end; )
{
if((cond = comp(a[mid],e)) == 0) return mid;
else if(cond > 0)
{
end = mid;
}
else
{
start = mid+1;
}
mid = start + (end-start)/2;
}
return -1;
}
2、使用递归实现
int recur_binary_search(int a[], int start, int end, int e, int(*comp)(int a, int e))
{
int mid = start+(end-start)/2;
int cond;
printf("mid = %d\n",mid);
if(start > end) return -1;
if((cond = comp(a[mid],e)) == 0) return mid;
else if(cond > 0)
{
end = mid;
}
else
{
start = mid+1;
}
return recur_binary_search(a,start,end,e,comp);
}
3、linux kernl的lib中,也有对二分法的实现:
实现的文件为:bsearch.c
大家可以查看。