二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好;其缺点是要求待查表为有序表,且插入删除困难。因此,折半查找方法适用于不经常变动而查找频繁的有序列表。
首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。
int search4(int array[], int n, int v)
{
int left, right, middle;
left = -1, right = n;
while (left + 1 != right)
//这个循环维持的条件是left<right && array[left]<v<=array[right],所以到最后的时候,
{
//如果可以找到目标,则只剩下两个数,并且满足 array[left]<v<=array[right],是要查找的数是right
middle = left + (right - left) / 2;
if (array[middle] < v)
//必须保证array[left]<v<=array[right],所以left = middle;
{
//如果left =middle+1,则有可能出现 array[left]<=v的情况
left = middle;
}
else
{
right = middle;
}
}
if (right >= n || array[right] != v)
{
right = -1;
}
return right;
}
可以用下面的算法,可以找出满足条件的数。
[cpp] view plaincopy
- int Bi_Search(int a[],int n,int b)//
- {//返回等于b的第一个
- if(n==0)
- return -1;
- int low = 0;
- int high = n-1;
- int last = -1;//用last记录上一次满足条件的下标
- while (low<=high)
- {
- int mid = low +(high-low)/2;
- if (a[mid]==b)
- {
- last = mid;
- high = mid -1;
- }
- else if(a[mid]>b)
- high = mid -1;
- else
- low = mid +1;
- }
- return last;
- }
- int Bi_Search1(int a[],int n,int b)//大于b的第一个数
- {
- if(n<=0)
- return -1;
- int last = -1;
- int low = 0;
- int high = n-1;
- while (low<=high)
- {
- int mid = low +(high – low)/2;
- if(a[mid]>b)
- {
- last = mid;
- high = mid -1;
- }
- else if (a[mid]<=b)
- {
- low =mid +1;
- }
- }
- return last;
- }