二分搜索有两种常见的实现方法:递归实现、迭代实现。其中递归实现的代码量是最少的(但计算机执行的代码却很多哦)。
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