二分查找:
(1)确定该区间的中点位置:mid=(low+high)/2
min代表区间中间的结点的位置,low代表区间最左结点位置,high代表区间最右结点位置
(2)将待查a值与结点mid的关键字(下面用R[mid].key)比较,若相等,则查找成功,否则确定新的查找区间:
如果R[mid].key>a,则由表的有序性可知,R[mid].key右侧的值都大于a,所以等于a的关键字如果存在,必然在R[mid].key左边的表中。这时high=mid-1
如果R[mid].key<a,则等于a的关键字如果存在,必然在R[mid].key右边的表中。这时low=mid
如果R[mid].key=a,则查找成功。
(3)下一次查找针对新的查找区间,重复步骤(1)和(2)
(4)在查找过程中,low逐步增加,high逐步减少,如果high<low,则查找失败。
实现方式有两种:
// 1、递归实现:
public static int binarySerach2(int[] array, int low, int high, int key){
int middle = (low+high)/2;
if (low > high) {
return -1;
}
if (array[middle] == key) {
return middle;
}else if (array[middle] > key) {
return binarySerach2(array, low, middle-1, key);
}else {
return binarySerach2(array, middle+1, high, key);
}
}
// 2、while循环实现:
public static int binarySerach(int[] array, int key){
int low = 0;
int high = array.length - 1;
int middle = 0;
while (low <= high) {
middle = (low+high)/2;
if (array[middle] == key) {
return middle;
}else if (array[middle] > key) {
high = middle - 1;
}else {
low = middle + 1;
}
}
return -1;
}
JDK自带实现:位于java.util.Arrays包中
public static int binarySearch(int[] a, int fromIndex, int toIndex,
int key) {
rangeCheck(a.length, fromIndex, toIndex);
return binarySearch0(a, fromIndex, toIndex, key);
}
// Like public version, but without range checks.
private static int binarySearch0(int[] a, int fromIndex, int toIndex,
int key) {
int low = fromIndex;
int high = toIndex - 1;
while (low <= high) {
int mid = (low + high) >>> 1;
int midVal = a[mid];
if (midVal < key)
low = mid + 1;
else if (midVal > key)
high = mid - 1;
else
return mid; // key found
}
return -(low + 1); // key not found.
}
// 健壮性判断
private static void rangeCheck(int length, int fromIndex, int toIndex) {
if (fromIndex > toIndex) {
throw new IllegalArgumentException(
"fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")");
}
if (fromIndex < 0) {
throw new ArrayIndexOutOfBoundsException(fromIndex);
}
if (toIndex > length) {
throw new ArrayIndexOutOfBoundsException(toIndex);
}
}