1.二分查找原理
首先,待查找的数组或集合必须是已经过排序的,本文以从小到大递增数组为例讲解。
选取数组中点,将待查找目标与数组中点的值做比较。
如果目标小于中点值,则在数组起始位到数组中点这一段再获取中点值与之比较。
如果目标大于中点值,则在数组中点到数组结束位这一段在获取中点值与之比较。
以此类推,直到找到目标或者遍历完整个数组未找到目标为止。
时间复杂度为O(logN)
2.二分查找实现(循环方式与递归方式,Java实现)
public class BinarySearch {
/**
* 循环方式实现二分查找
*
* @param array
* 已从小到大排序的数组
* @param target
* 待查找的值
* @return 待查找值的下标,如果不存在则返回-1
*/
public int searchByLoop(int[] array, int target) {
int low = 0;
int high = array.length - 1;
while (low < high) {
int mid = (low + high) >> 1;
if (target == array[mid]) {
return mid;
} else if (target > array[mid]) {
if (target != array[high]) // 判断target是否在数组的最右
low = mid + 1;
else
return high;
} else {
if (target != array[low]) // 判断target是否在数组的最左
high = mid - 1;
else
return low;
}
}
return -1;
}
/**
* 递归实现二分查找
*
* @param array
* 已从小到大排序的数组
* @param target
* 待查找的值
* @param low
* 数组最小值位
* @param high
* 数组最大值位
* @return 待查找值的下标,如果不存在则返回-1
*/
public int searchByRecursive(int[] array, int target, int low, int high) {
int mid = (low + high) >> 1;
if (low < high) {
if (target == array[mid]) {
return mid;
} else if (target > array[mid]) {
if (target != array[high])
return searchByRecursive(array, target, mid + 1, high);
else
return high;
} else {
if (target != array[low])
return searchByRecursive(array, target, low, mid - 1);
else
return low;
}
}
return -1;
}
}
*我发现许多其它博客里的代码都没有判断目标是否在起始位或结束位,然而我在测试的时候将目标值选为起始位或结束位会出现找不到的问题。分析一下是因为当中点遍历到顶端位前一位时,因为(low<high)条件的存在,不会再去判断顶端位,导致问题的出现。