二分查找的前提是:所要查找的数组必须是有序的!
核心算法:
- 找到数组的中点下标mid
- 如果所要查找的值比mid下标对应的值小,那么要向数组的左半部分进行查找
- 如果所要查找的值比mid下标对应的值大,那么要向数组的右半部分进行查找
- 如果所要查找的值与mid下标对应的值相同,就返回mid
- 若所要查找的数组为空,则返回-1
- 递归实现上述过程(也可以用循环代替递归)
算法代码
import java.util.Arrays;
public class BinarySearch {
private static int[] myArr;
private BinarySearch() {
}
public static BinarySearch instance(int[] arr) {
myArr = arr;
return new BinarySearch();
}
/**
*
* @Title: binarySearch
* @Description: 递归实现二分查找
* @param: @param
* left 当前所要查找的数组的第一个元素的下标
* @param: @param
* right 当前所要查找的数组的最后一个元素的下标
* @param: @param
* value 所要查找的值
* @return: int 所要查找的值在数组中的下标,若找不到,则返回-1
*/
private int binarySearch(int left, int right, int value) {
// 如果当前数组不为空
if (left <= right) {
int mid = (left + right) / 2;// 找到数组的中点下标mid
// 如果所要查找的值比mid下标对应的值小,那么要向数组的左半部分进行查找
if (value < myArr[mid]) {
right = mid - 1;
return binarySearch(left, right, value);
} else if (value > myArr[mid]) {// 如果所要查找的值比mid下标对应的值大,那么要向数组的右半部分进行查找
left = mid + 1;
return binarySearch(left, right, value);
} else {// 如果所要查找的值与mid下标对应的值相同,就返回mid
return mid;
}
}
// 若所要查找的数组为空,则返回-1
return -1;
}
/**
*
* @Title: binarySearchs
* @Description: binarySearch的升级版,找出数组中所有符合所查找值的下标
* @param: @param left
* @param: @param right
* @param: @param value
* @return: int[] 存放所有下标的数组,没有找到则返回null
*/
private int[] binarySearchs(int left, int right, int value) {
// 如果当前数组不为空
if (left <= right) {
int mid = (left + right) / 2;// 找到数组的中点下标mid
// 如果所要查找的值比mid下标对应的值小,那么要向数组的左半部分进行查找
if (value < myArr[mid]) {
right = mid - 1;
return binarySearchs(left, right, value);
} else if (value > myArr[mid]) {// 如果所要查找的值比mid下标对应的值大,那么要向数组的右半部分进行查找
left = mid + 1;
return binarySearchs(left, right, value);
} else {// 如果所要查找的值与mid下标对应的值相同,就查找该下标的左边和右边的元素,把所有与所查找值相同的元素都放到返回数组里
int[] returnArr = new int[right - left + 1];//创建返回数组
int k = 0;
int n = mid - 1;
//查找mid下标的左半部分元素
while(n >= left && myArr[n] == value) {
returnArr[k++] = n;
n--;
}
returnArr[k++] = mid; //把mid下标放入返回数组
n = mid + 1;
//查找mid下标的右半部分元素
while(n <= right && myArr[n] == value) {
returnArr[k++] = n;
n++;
}
return Arrays.copyOf(returnArr, k);//返回所有找到的下标构成的数组
}
}
// 若所要查找的数组为空,则返回null
return null;
}
/**
*
* @Title: binarySearch
* @Description: 二分查找入口 (返回所查找值的第一个下标)
* @param: @param value 所要查找的值
* @return: int 查找的值在数组中的下标,没有找到则返回-1 @throws
*/
public int binarySearch(int value) {
return binarySearch(0, myArr.length - 1, value);
}
/**
*
* @Title: binarySearchs
* @Description: 二分查找入口 (返回所查找值对应的多个下标集合)
* @param: @param value 所要查找的值
* @return: int 查找的值在数组中的下标,没有找到则返回-1 @throws
*/
public int[] binarySearchs(int value) {
return binarySearchs(0, myArr.length - 1, value);
}
}
源码:github地址