二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,折半查找要求线性表必须采用顺序存储结构。
二分查找法虽然有很多不同的写法,但是殊途同归,大多都是改变了左右边界的取值以及中间比较值的计算方法。
下面是一种最常用的写法:
/*
二分查找
入口参数:指向已经排序完的顺序表表头的指针,表中元素个数,待查找的数值
返回值:指向待查找元素的指针,不满足要求返回NULL
*/
int *BinarySearch(int ar[], int num, int elem)
{
if (num <= 0)
return NULL;
int left = 0, right = num - 1; //定义左右边界
int compare_index = (right - left) / 2; //定义比较值数组的下标
int compare = ar[compare_index]; //定义比较值
//当查找值不等于比较值时一直查找
while (elem != compare)
{
//通过二分查找的思想对左右边界重新赋值
if (elem < compare)
right = compare_index - 1;
else
left = compare_index + 1;
//终止:搜索区间为空
if (left > right)
return NULL;
//更新比较元素的下标:左边界值加上一个偏移量
compare_index = left + (right - left) / 2;
compare = ar[compare_index];//更新比较值
}
return &ar[compare_index]; //返回指向查找值元素的指针
}
算法虽然简单,但是在写的时候很容易犯错,要注意以下几点:
1.左右边界尽量取闭区间,这样可以避免出现溢出的情况。
2.左右边界的计算尽量采取以下方法:
left = compare_index + 1
right = compare_index - 1
原因是:这样能保证边界上的值始终是没有被访问的,而且还会给查找终止条件提供便利,如果用left = compare_index 或 right = compare_index ,那么左右边界就无法出现left > right 的情况,终止条件的编写可能会更加麻烦些
3.比较值通常采用以下方法算出
compare_index = left + (right - left) / 2