目录
一、概述
二分查找的前提为数组必须有序, 排序算法详见第八章
二、思路分析
三、二分查找实现 -- 单一查找
/**
* @Description 二分查找: 数组必须有序
* @Version V1.0
*/
public class BinaryLookup {
public static void main(String[] args) {
int[] arr = {1, 8, 10, 89, 1000, 1234};
int index = getBinarySearch(arr, 0, arr.length - 1, 200);
if (index == -1) {
System.out.println("没有找到!!!");
} else {
System.out.println("该元素的下标: " + index);
}
}
/**
*
* @Description 普通二分查找法
* @param arr 存放元素的数组
* @param left 左侧数组索引值
* @param right 右侧数组索引值
* @param value 要查找的元素
* @return int -1 没有找到, 否则返回 value 对应的下标
*/
public static int getBinarySearch (int[] arr, int left, int right, int value) {
if (left > right) {
return -1;
}
int mid = (left + right) / 2;
if (value > arr[mid]) {
return getBinarySearch(arr, mid+1, right, value);
} else if (value < arr[mid]){
return getBinarySearch(arr, left, mid-1, value);
} else {
return mid;
}
}
}
四、查找一个元素多个下标值
/**
*
* @Description 课后问题:
* {1,8, 10, 89, 1000, 1000,1234} 当一个有序数组中,
* 有多个相同的数值时,如何将所有的数值都查找到,比如这里的 1000.
* TODO 思路
* 1. 在找到对应的值时, 不直接返回 mid
* 2. 向 mid 索引值的左边进行扫描, 将所有满足查找值的下标保存在List集合中
* 3. 向 mid 索引值的右边进行扫描, 将所有满足查找值的下标保存在List集合中
* 4. 返回List集合
* @param arr 存放元素的数组
* @param left 左侧数组索引值
* @param right 右侧数组索引值
* @param value 要查找的元素
* @return List 集合为空 没有找到, 否则返回 value 对应的所有下标
*/
public static List<Integer> getBinarySearchList (int[] arr, int left, int right, int value) {
List<Integer> list = new ArrayList<>();
if (left > right) {
return list;
}
int mid = (left + right) / 2;
if (value > arr[mid]) {
return getBinarySearchList(arr, mid+1, right, value);
} else if (value < arr[mid]){
return getBinarySearchList(arr, left, mid-1, value);
} else {
int temp = mid - 1;
// 向 mid 索引值的左边进行扫描, 将所有满足查找值的下标保存在List集合中
while (temp >= 0 && arr[temp] == value)
list.add(temp--);
// 将中间值保存在集合中
list.add(mid);
// 向 mid 索引值的右边进行扫描, 将所有满足查找值的下标保存在List集合中
temp = mid + 1;
while (temp <= right && arr[temp] == value)
list.add(temp++);
return list;
}
}