二分查找法是对一组有序的数字中进行查找,传递相应的数据,进行比较查找到与原数据相同的数据,查找到了返回对应的数组下标,没有找到返回-1;
1、基本二分查找实现
while循环
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23/**
* 循环实现
* @param array 已排序数组
* @param target 目标
* @return 找不到返回-1,找到返回下标
*/
private static int binarySearch(int[] array, int target) {
int low = 0;
int high = array.length - 1;
while (low <= high) {
int mid = low + (high - low) / 2; //注意此处写法,避免越界
if (array[mid] > target) {
high = mid - 1;
} else if (array[mid] < target) {
low = mid + 1;
} else {
return mid;
}
}
return -1;
}递归实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15private static int binarySearch(int[] array, int target, int low, int high) {
int mid = low + (high - low) / 2;
if (array[mid] == target) {
return mid;
}
if (low >= high) {
return -1;
} else if (target > array[mid]) {
return binarySearch(array, target, mid + 1, high);
} else if (target < array[mid]) {
return binarySearch(array, target, low, mid - 1);
}
return -1;
}
2、变形
随着二分查找的进行,如果找到key并不结束循环的话,最终的结束状态会是right < left,并且right + 1 = left。
- 当数组中存在key时,根据二分区间选择的不同,这里又分为两种情况,如下图(key为2时)
- 当数组中不存在key时,最后仅有一种情况,即把图中的红色框框去掉。
那么,可以找到:
- 最后一个小于key的元素 1 左right
- 第一个大于等于key的元素 2 左left
- 最后一个小于等于key的元素 2 右right
- 第一个大于key的元素 5 右left
另外,如果存在多个key时,稍加判断,就可以找到
- 第一个与key相等的元素
- 最后一个与key相等的元素
1 | while (left <= right) { |
根据要求的值的位置,先确定比较符号,再确定返回值,
比较符号:左<=,右<
返回值:左right,右left
2.1 查找最后一个小于key的元素
1 | //1 查找最后一个小于key的元素 |
2.2 查找第一个大于等于key的元素
1 | //2 查找第一个大于等于key的元素 |
2.3 查找最后一个小于等于key的元素
1 | //3 查找第一个大于等于key的元素 |
2.4 查找第一个大于key的元素
1 | //4 查找第一个大于key的元素 |
2.5 查找第一个与key相等的元素
1 | //5 查找第一个与key相等的元素 |
2.6 查找最后一个与key相等的元素
1 | //6 查找最后一个与key相等的元素 |