思路:
前提:被查找数组是有序的
- 确定要查找的数组范围,通常用两个指针
left
和right
表示,初始时left
指向第一个元素,right
指向最后一个元素。 - 计算数组的中间位置
mid
,可以使用(left + right) / 2
来得到。 - 将目标值与中间位置的元素进行比较:
- 如果目标值等于中间位置的元素,则找到了目标值,返回中间位置。
- 如果目标值小于中间位置的元素,则说明目标值在左半部分,更新
right
为mid - 1
,继续执行步骤2。 - 如果目标值大于中间位置的元素,则说明目标值在右半部分,更新
left
为mid + 1
,继续执行步骤2。
- 重复执行步骤2和步骤3,直到找到目标值或者
left
大于right
,表示未找到目标值。
代码实现
/**
* @param arr 查找的数组
* @param left 左边的索引
* @param right 右边的索引
* @param value 查找的值
* @return 返回下标,没有返回-1
*/
public static int binarySearch(int[] arr, int left, int right, int value) {
if (left > right)
return -1;
int mid = (left + right) / 2;
int midVal = arr[mid];
if (value > midVal) {
//向右递归
return binarySearch(arr, mid + 1, right, value);
} else if (value < midVal) {
//向左递归
return binarySearch(arr, left, mid - 1, value);
} else
return mid;
}
当被查找数组里面有重复元素时
public static ArrayList<Integer> binarySearch(int[] arr, int left, int right, int value) {
if (left > right) {
return new ArrayList<Integer>();
}
int mid = (left + right) / 2;
int midVal = arr[mid];
if (value > midVal) {
//向右递归
return binarySearch(arr, mid + 1, right, value);
} else if (value < midVal) {
//向左递归
return binarySearch(arr, left, mid - 1, value);
} else {
ArrayList<Integer> resIndexList = new ArrayList<>();
int temp = mid - 1;
while (true) {
if (temp < 0 || arr[temp] != value) {
break;
}
resIndexList.add(temp);
temp--;
}
resIndexList.add(mid);
temp = mid + 1;
while (true) {
if (temp > arr.length - 1 || arr[temp] != value) {
break;
}
resIndexList.add(temp);
temp++;
}
return resIndexList;
}
}
binarySearch方法
binarySearch方法为二分法查找,是Arrays包里面的
1.binarySearch(Object[], Object key)
方法的object[]参数是要查找的数组,key参数为要查找的key值。
这个函数返回目标元素在数组中的索引,如果找到了目标元素。如果未找到目标元素,则返回一个负数,表示该元素在数组中的插入点位置的相反数减1
2.binarySearch(Object[], int fromIndex, int toIndex, Object key)
方法的object[]参数为要查找的数组,fromindex参数为开始索引(包括),toindex为结束索引(不包括),两个参数之间为查找的范围。key为要查找的key。
例子
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] array = {1, 2, 3, 4, 5, 6};
int key = 4;
int index = Arrays.binarySearch(array, key);
if (index >= 0) {
System.out.println("找到了目标元素,索引为:" + index);
} else {
System.out.println("未找到目标元素,应插入的位置为:" + (-index - 1));
}
}
}
3.public static <T> int binarySearch(T[] a, T key, Comparator<? super T> c)
T[] a
表示要进行二分查找的数组。T key
表示要查找的目标元素。Comparator<? super T> c
是一个比较器对象,用于指定元素之间的比较规则。
使用这个重载版本的方法,我们需要提供一个实现了Comparator
接口的比较器对象c
,并在其中实现compare
方法来定义元素之间的比较规则。然后将这个比较器对象传递给binarySearch
方法,这样就可以在自定义的比较规则下执行二分查找
例子:
import java.util.Arrays;
import java.util.Comparator;
public class Main {
public static void main(String[] args) {
String[] array = {"apple", "banana", "orange", "pear", "grape"};
String key = "orange";
// 自定义比较器,按照字符串长度进行比较
Comparator<String> lengthComparator = new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return s1.length() - s2.length();
}
};
// 使用自定义比较器进行二分查找
int index = Arrays.binarySearch(array, key, lengthComparator);
if (index >= 0) {
System.out.println("找到了目标元素,索引为:" + index);
} else {
System.out.println("未找到目标元素,应插入的位置为:" + (-index - 1));
}
}
}