二分查找
1.概述
二分查找是针对有序数列的,对无序数列是无效的,在有序序列中使用二分查找能大大提高查找效率。
以升序数列为例,比较一个元素与数列中的中间位置的元素的大小,如果比中间位置的元素大,则继续在后半部分的数列中进行二分查找;如果比中间位置的元素小,则在数列的前半部分进行比较;如果相等,则找到了元素的位置。每次比较的数列长度都会是之前数列的一半,直到找到相等元素的位置或者最终没有找到要找的元素。
2.代码实现
二分查找非递归
public class BinarySearchNoRecur {
public static void main(String[] args) {
// 测试
int[] arr = {1, 3, 8, 10, 11, 67, 100};
int index = binarySearch(arr, 11);
System.out.println("index=" + index);//
}
/*
* @param arr: arr是升序排列
* @param target:
* @return: int
* @return: -1 表示没查找到
* @description:二分查找非递归实现
*/
public static int binarySearch(int arr[], int target) {
int left = 0;
int right = arr.length - 1;
while (left <= right) { // 要继续查找
int mid = (left + right) / 2;
if (arr[mid] == target) {
return mid;
} else if (arr[mid] > target) {
right = mid - 1; // 需要向左边查找
} else {
left = mid + 1; // 需要向右边查找
}
}
return -1;
}
}
二分查找非递归实现
public class BinarySearch {
public static void main(String[] args) {
int arr[] = {1,8,10,89,102,222};
int i = binarySearch(arr,0,arr.length-1, 222);
System.out.println("下标为:"+i);
}
/*
* @param arr: 传入的数组
* @param left: 数组左边的索引
* @param right: 数组右边的索引
* @param v: 要查找的值
* @return: int
* @description: 二分查找必须传入一个有序的数组
*/
public static int binarySearch(int arr[],int left,int right,int findV){
int mid = (left + right) / 2; //中间的索引
int midV = arr[mid];
if (left > right){
return -1;
}
if (findV > midV){ //向右递归
return binarySearch(arr,mid+1,right,findV);
}
if (findV < midV){
return binarySearch(arr,left,mid-1,findV);
}
else
return mid;
}
}
简单完善
public class BinarySearch {
public static void main(String[] args) {
int arr[] = {1,8,10,10,10,10,10,89,102,222};
ArrayList integers = binarySearch(arr, 0, arr.length - 1, 10);
System.out.println("下标为:"+integers);
}
/*
* @param arr: 传入的数组
* @param left: 数组左边的索引
* @param right: 数组右边的索引
* @param v: 要查找的值
* @return: int
* @description: 二分查找必须传入一个有序的数组
*/
public static ArrayList binarySearch(int arr[],int left,int right,int findV){
int mid = (left + right) / 2; //中间的索引
int midV = arr[mid];
if (left > right){ //没有找到结束递归
return new ArrayList<>();
}
if (findV > midV){ //向右递归
return binarySearch(arr,mid+1,right,findV);
}
if (findV < midV){
return binarySearch(arr,left,mid-1,findV);
}
else {
/*
*1.在找到mid后不要马上返回
*2.继续向左或向右扫描 找到满足的下标 加入到集合
*3.返回集合
* @description:
*/
ArrayList index = new ArrayList<>();
int temp = mid - 1;
while (true){
if (temp < 0 || arr[temp] !=findV){
break;
}
//否则 将下标放入index
index.add(temp);
temp--;
}
index.add(mid);
temp = mid + 1;
while (true){
if (temp > right || arr[temp] !=findV){
break;
}
//否则 将下标放入index
index.add(temp);
temp++;
}
return index;
}
}
}