二分查找算法java 21行代码实现
二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。
前置知识要求:
了解java集合(强制要求)
了解递归(半强制要求)
了解包装类(不是必需)
了解泛型(不是必需)
通过二次分解中值比较,最多7次左右就可以找到查找值
import java.util.ArrayList;
import java.util.List;
/**
* 二分查找的前提是有序数组
*/
public class BinarySearch {
public static void main(String[] args) {
int[] arr = {1,8,10,89,1000,1000,1000,1000,1234};
List<Integer> integers = binarySearch(arr, 1000);
integers.forEach(System.out::println);
}
/**
* 二分查找算法
* @param arr 查找数组,数组要求是从小到大排序
* @param findVal 查找的值
* @return 成功:返回一个列表对象,里面存放所有找到的值的下标。失败:返回空list
*/
public static List<Integer> binarySearch(int[] arr,int findVal){
ArrayList<Integer> result = new ArrayList<>();
binarySearch(arr,0,arr.length-1,findVal,result);
return result;
}
/**
* 二分查找算法
* @param arr 查找数组,数组要求是从小到大排序
* @param left 左下标
* @param right 右下标
* @param findVal 查找的值
*/
private static void binarySearch(int[] arr,int left,int right,int findVal,List<Integer> result){
//之所以不写大于等于是因为这个点可能是要找的结果值
//也就是left == right,假设arr[left]就是我要找的值呢?
//最后的if代码会知道的
if(left > right){
//走到这一步了,没有找到
return;
}
//mid,中值
//(1)假设左右下标都相等,相加再除以2结果是不变的6+6/2 = 6
//(2)那么下面的两个if就算进去了也是立马退出来的死胡同(注*1),只有第3个if是有效的
int mid = (right + left) / 2;
if(findVal <= arr[mid]){
//上面的mid中值做了宽容处理,但是递归内不行,需要减1,否则会陷入死龟
//而如果真的findVal==arr[mid],最后的if代码也能知道并加入集合
binarySearch(arr, left, mid-1, findVal, result);
}
if(findVal >= arr[mid]){
//增加left值,防止死龟
binarySearch(arr, mid+1, right, findVal, result);
}
//最后的if代码
if(findVal == arr[mid]){
result.add(mid);
}
/*
注1:之所以说是死胡同是因为binarySearch(arr, left, mid-1, findVal, result);
mid-1了,本来是left==right,现在就是left>right了
*/
}
}
代码运行结果:
5
7
6
4
进程已结束,退出代码为 0
如数组的下标一样
int[] arr = {1,8,10,89,1000,1000,1000,1000,1234};
1000全部找到