在对线性表的操作中,经常需要查找一个元素在表中的位置。通常最坏的办法是遍历整个线性表,以找到某元素的位置或者不在表中。 但是如果线性表是有序的,比如由小到大递增(完全可以是自定义的比较方法),那么在这种情况下使用二分查找法会是首选。当然,这么重要的函数,一般的库都会提供,比如:

C provides bsearch() in its standard library.

C++’s STL provides algorithm functions binary_search, lower_bound and upper_bound.

Java offers a set of overloaded binarySearch() static methods in the classes Arrays and Collections in the standard > java.util package for performing binary searches on Java arrays and on Lists, respectively. They must be arrays of > primitives, or the arrays or Lists must be of a type that implements the Comparable interface, or you must specify a > custom Comparator object.

Microsoft’s .NET Framework 2.0 offers static generic versions of the binary search algorithm in its collection base > classes. An example would be System.Array’s method BinarySearch(T[] array, T value).

Python provides the bisect module.

COBOL can perform binary search on internal tables using the SEARCH ALL statement.

Perl can perform a generic binary search using the CPAN module Search::Binary.[7]

Go’s sort standard library package contains functions Search, SearchInts, SearchFloat64s, and SearchStrings, which > implement general binary search, as well as specific implementations for searching slices of integers, floating-point > numbers, and strings, respectively.[3]

For Objective-C, the Cocoa framework provides the NSArray -indexOfObject:inSortedRange:options:usingComparator: method > in Mac OS X 10.6+. Apple’s Core Foundation C framework also contains a CFArrayBSearchValues() function.

(以上文字摘自wikipedia)

但是,正如“编程珠玑”语言的,90%的程序员却不能在第一次写出无bug的二分查找算法,虽说二分查找的思想很简单,但一实现就不免有疏漏。下面提供一段本人用C写的二分查找算法。

#include <stdio.h>
/*
* array_num 表示数组的元素个数
* 本算法只是实现了递增排序,即operator <
*/

void sort_int(int *array, int array_num)
{
for (int i=0;i<array_num;++i)
{
for (int j=0;j<array_num-1-i;++j)
{
if (array[j] > array[j+1])
{
int tmp = array[j];
array[j] = array[j+1];
array[j+1] = tmp;
}
}
}
}

/*
* if found, return index; else return -1
* 注意:搜寻区间是[low_index,high_index],即闭区间
*/

int b_search(int *array, int low_index, int high_index, int key)
{
while(low_index<=high_index)
{
int mid = (low_index+high_index)/2;
if (key==array[mid])
return mid;
else if (key < array[mid])
high_index=mid-1;
else
low_index=mid+1;
}
return -1;
}

/*test program*/
int main()
{
int array[] = {2, 2, 4, 5, 6, -1, 4, 5, 6, 7, 8, 8};
int num=sizeof(array)/sizeof(int);

sort_int(array, num); //sorting

if (b_search(array, 0, num-1, 7)>=0) //searching
printf("found\n");
else
printf("not found\n");

return 0;
}

观察上面的b_search()函数,可以看到用递归的方式实现也会是一个很好的办法。

递归实现:

#include <stdio.h>

/*
* array_num 表示数组的元素个数
* 本算法只是实现了递增排序,即operator <
*/

void sort_int(int *array, int array_num)
{
for (int i=0;i<array_num;++i)
{
for (int j=0;j<array_num-1-i;++j)
{
if (array[j] > array[j+1])
{
int tmp = array[j];
array[j] = array[j+1];
array[j+1] = tmp;
}
}
}
}

/*
* if found, return index; else return -1
* 注意:搜寻区间是[low_index,high_index],即闭区间
*/

int b_search(int *array, int low_index, int high_index, int key)
{
if (low_index > high_index)
return -1;
else
{
int mid = (low_index+high_index)/2;
if (key == array[mid])
return mid;
else if (key < array[mid])
return b_search(array, low_index, mid-1, key);
else
return b_search(array, mid+1, high_index, key);
}
}

/*test program*/
int main()
{
int array[] = {2, 2, 4, 5, 6, -1, 4, 5, 6, 7, 8, 8};
int num=sizeof(array)/sizeof(int);

sort_int(array, num); //sorting

if (b_search(array, 0, num-1, 7)>=0) //searching
printf("found\n");
else
printf("not found\n");

return 0;
}

参考资料:Binary search algorithm (From wikipedia)