折半查找是使用广泛的查找算法,可采用递归及非递归实现方式。
折半查找最适合情况符合要求如下要求:
1、源数据必须是有序的。
2、源数据中不存在重复数据(如果存在重复数据,需要做特殊处理,如:查到数据后在顺序向前及向后查找相邻的相同数据)。
java简单实现代码如下:
/**
* <p>
* 对有序数组进行二分查找(递归查找)
* </p>
* <p>
* 折半查找采用递归,最多递归次数为log(high-low)+1
* </p>
*
* @param arr
* 有序数组(不存在重复数据)
* @param k
* 要查找的数据
* @param low
* 数组起始位置
* @param hight
* 数组结束位置
* @return 要查找的数据在数组中的下标
*/
public static int binarySearchRecursion(int[] arr, int k, int low, int hight) {
if (low < 0 || hight >= arr.length) {
throw new java.lang.ArrayIndexOutOfBoundsException();
}
if (low > hight) {
return -1;
}
int mid = (low + hight) >> 1;
if (arr[mid] == k) {
return mid;
}
if (k < arr[mid]) {
return binarySearchRecursion(arr, k, low, mid - 1);
} else {
return binarySearchRecursion(arr, k, mid + 1, hight);
}
}
/**
* <p>
* 对有序数组进行二分查找(非递归查找)
* </p>
*
* @param arr
* 有序数组(不存在重复数据)
* @param k
* 要查找的数据
* @param low
* 数组起始位置
* @param hight
* 数组结束位置
* @return 要查找的数据在数组中的下标
*/
public static int binarySearch(int[] arr, int k, int low, int hight) {
if (low < 0 || hight >= arr.length) {
throw new java.lang.ArrayIndexOutOfBoundsException();
}
if (low > hight) {
return -1;
}
int mid = 0;
while (hight >= low) {// 最坏循环次数log(high-low)+1
mid = (hight + low) >> 1;
if (arr[mid] == k) {
return mid;
}
if (k < arr[mid]) {
hight = mid - 1;
} else {
low = mid + 1;
}
}
return -1;
}