二分查找的三种写法

"编程珠玑"一书中说到90%的程序员都无法写出没有BUG的二分查找,这个看似简单的算法着实隐藏着一些陷阱让人容易犯错误。

最简单的二分查找算法如下,没什么好说的,只要仔细不会犯错误。

int bsearch(int a[], int size, int v)
{
    int mid, low = 0, high = size - 1;
    while(low <= high){
	mid = low + (high - low) / 2;
	if(a[mid] == v)
	    return mid;
	else if(a[mid] < v)
	    low = mid + 1;
	else
	    high = mid - 1;
    }
    return -1;
}

上面这种二分查找方法找出来的下标值是没有特点的,比如对于数组 int data[] = {1,2,2,4,5,5,5,5,5,7,8,9,9,10,12} 调用 bsearch(data, 15, 5) 返回结果是7。这显然没错,但是该数组从 data[4] 到 data[8] 的值都是5,如果想找到数值为5的第一个数组下标和数值为5的最后一个数组下标(分别为4和8)该如何做呢?那我们的二分查找就要作一些修改了。


返回第一个符合要求的数组下标:

int bsearch_low(int a[], int size, int v)
{
    int mid, low = 0, high = size - 1;
    while(low < high){
	mid = low + (high - low) / 2;
	if(a[mid] >= v)
	    high = mid;
	else
	    low = mid + 1;
    }
    if(a[low] == v)
	return low;
    else
	return -1;
}

返回最后一个符合要求的数组下标:

int bsearch_high(int a[], int size, int v)
{
    int mid, low = 0, high = size - 1;
    while(low < high){
	mid = low + (high - low + 1) / 2;
	if(a[mid] <= v)
	    low = mid;
	else
	    high = mid -1;
    }
    if(a[low] == v)
	return low;
    else
	return -1;
}



你可能感兴趣的:(Data,Structures,&&,Algorithm)