9. 二分查找
二分查找是对有序数组进行查找
思路:
- 首先确定该数组中间的下标
- 然后让需要查找的数 和 中间数组的数进行比较
- 如果需要查找的数比中间数组的数大,那么需要递归向右进行查找
- 如果需要查找的数比中间数组的数小,那么需要递归向左进行查找
- 如果相等,就算找到
- 结束条件
- 找到,结束递归
- 递归完整个数组,仍需要递归
package search;
public class BinarySearch {
// 使用二分查找,数组必须是有序的
public static void main(String[] args) {
int[] arr = {1, 8, 10, 89, 1000, 1234};
int resIndex = binarySearch(arr, 0, arr.length - 1, 1);
System.out.println(resIndex);
}
// 二分查找
/**
*
* @param arr 数组
* @param left 左边的索引
* @param right 右边的索引
* @param findVal 要查找的数
* @return
*/
public static int binarySearch(int[] arr, int left, int right, int findVal){
// 当left > right 时,说明递归整个数组没有找到
if (left > right){
return -1;
}
int mid = (left + right) / 2;
int midVal = arr[mid];
if (midVal > findVal){
return binarySearch(arr, left,mid-1, findVal);
}else if (midVal < findVal){
return binarySearch(arr, mid + 1, right, findVal);
}else{
return mid;
}
}
}
9.1 二分查找(优化)
**问题:**当一个有序数组存在多个相同的数值时,如何把他们全部查找出来
思路:
1. 在找到mid值时,不要马上返回
2. 向mid索引值的左边扫描,将所有满足查找值的下标,加入到`ArrayList`
3. 向mid索引值的左边扫描,将所有满足查找值的下标,加入到`ArrayList`
package search;
import java.util.ArrayList;
import java.util.List;
public class BinarySearch {
// 使用二分查找,数组必须是有序的
public static void main(String[] args) {
int[] arr2 = {1, 8, 10, 89, 1000, 1000, 1000, 1234};
List<Integer> list = binarySearch2(arr2, 0, arr.length - 1, 1000);
System.out.println("resultIndexList = "+ list);
}
/**
*
* @param arr 数组
* @param left 左边的索引
* @param right 右边的索引
* @param findVal 要查找的数
* @return
*/
public static ArrayList<Integer> binarySearch2(int[] arr, int left, int right, int findVal){
// 当left > right 时,说明递归整个数组没有找到
if (left > right){
return new ArrayList<Integer>();
}
int mid = (left + right) / 2;
int midVal = arr[mid];
if (midVal > findVal){
return binarySearch2(arr, left,mid-1, findVal);
}else if (midVal < findVal){
return binarySearch2(arr, mid + 1, right, findVal);
}else{
/*
1. 在找到mid值时,不要马上返回
2. 向mid索引值的左边扫描,将所有满足查找值的下标,加入到`ArrayList`
3. 向mid索引值的左边扫描,将所有满足查找值的下标,加入到`ArrayList`
*/
ArrayList<Integer> resIndexList = new ArrayList<>();
resIndexList.add(mid);
// 先让temp向左移
int temp = mid - 1;
while(true){
if (temp < 0 || arr[temp] != findVal){
break;
}
// 否则,就把temp放进resIndex中
resIndexList.add(temp);
temp -= 1; // temp 左移
}
temp = mid + 1;
while(true){
if (temp > arr.length || arr[temp] != findVal){
break;
}
// 否则,就把temp放进resIndex中
resIndexList.add(temp);
temp += 1; // temp 左移
}
return resIndexList;
}
}
}