二分搜索有两种常见的实现方法:递归实现、迭代实现。其中递归实现的代码量是最少的(但计算机执行的代码却很多哦)。
public static int binarySearch(int a[], int x, int left, int right) {
if (left > right) {
return -1;
} else {
int mid = (left + right) / 2;
if (x == a[mid]) {
return mid;
}
if (x > a[mid]) {
return binarySearch(a, x, mid + 1, right);//***
} else {
return binarySearch(a, x, left, mid);//***
}
}
}
代码中有注释***的两句就是递归调用啦!我任然记得:老师说每届学生都纠结于这两句里的return能不能删掉。我的理解是:binarySearch是一个有返回值的函数。这就会有两个要求:1、执行该函数时,得保证它有返回值;2、调用该函数时,一般要有个与它返回值类型相同类型的变量接收它(有些时候返回值就是一个标识,这种情况除外)。
显然要求2可以说明问题了,但对于正在纠结的人可能说服力不是那么大。那么,就请继续仔细看看代码会如何执行。
public static int binarySearch(int a[], int x, int left, int right) {
if (left > right) {
return -1;
} else {
int mid = (left + right) / 2;
if (x == a[mid]) {
return mid;
}
if (x > a[mid]) {
binarySearch(a, x, mid + 1, right);//***
} else {
binarySearch(a, x, left, mid);//***
}
// ***statement ***
}
}
我们清楚这个递归不会是死递归,在最后一次调用(假设为第N次调用)中,return -1; 或return mid; 会被执行。这样回到了第 N-1 次调用的函数体,代码接着往下执行到 ***statement*** 接着第 N-1 次调用走完了。恍然大悟,这次调用是没有返回值的。
至此,道理讲明了。作为个人学习,顺便贴上些其它的实现代码。
public static int BinarySearch(int[] array, int key)
{
int low = 0;
int high = array.Length - 1;
int middle = 0;
while (low <= high)
{
middle = (low + high) / 2;
int middleValue = array[middle];
if (middleValue < key)
{
low = middle + 1;
}
else if (middleValue > key)
{
high = middle - 1;
}
else
{
return middle;
}
}
return -(low + 1);
}
此代码来自CSDN博客:http://blog.csdn.net/xzjxylophone/archive/2009/10/23/4714326.aspx
public static int BinarySearchIteration(int[] array, int key)
{
int low = 0;
int high = array.Length - 1;
int middle = 0;
while (low < high)
{
middle = (low + high) / 2;
if (key > array[middle])
{
low = middle + 1;
}
else
{
high = middle;
}
}
if (low > high)
{
return -1;
}
else
{
if (key == array[low])
{
return low;
}
else
{
return -1;
}
}
}
本代码来自CSDN博客:http://blog.csdn.net/xzjxylophone/archive/2009/10/23/4714326.aspx