思想比较简单,就直接贴代码了
/**
* 递归的二分查找,查找单个值
* 时间复杂度:log2n
* 有点像二叉排序树的查找
* @param arr 待查找数组,有序
* @param low
* @param high
* @param findVal 待找值
* @return 待找值的下标,没有返回-1
*/
public static int binarySearch(int[] arr,int low,int high,int findVal){
//说明没找到值
if (low > high){
return -1;
}
//比较值
int mid;
mid = ( low + high ) / 2;
//在右边找
if (findVal > arr[mid]){
return binarySearch(arr,mid+1,high,findVal);
}
//在左边找
else if (findVal < arr[mid]){
return binarySearch(arr,low,mid-1,findVal);
}
//上面都不成立,则找到值
else {
return mid;
}
}
/**
* 优化
* 递归的二分查找,查找可能有多个相同值
* 时间复杂度: log2n
* 有点像二叉排序树的查找
*
* 思路:找到第一个,往它的左边遍历,右边遍历时再添加,像打太极一样,扫过去扫回来,看似打酱油,实则暗藏杀机
* @param arr 待查找数组,有序
* @param low
* @param high
* @param findVal 待找值
* @return 待找值的下标,没有返回-1
*/
public static ArrayList<Integer> binarySearch2(int[] arr, int low, int high, int findVal){
//说明没找到值
if (low > high){
return new ArrayList<>();
}
//比较值
int mid;
mid = ( low + high ) / 2;
//在右边找
if (findVal > arr[mid]){
return binarySearch2(arr,mid+1,high,findVal);
}
//在左边找
else if (findVal < arr[mid]){
return binarySearch2(arr,low,mid-1,findVal);
}
//上面都不成立,则找到值
else {
ArrayList<Integer> resIndexList = new ArrayList<>();
//遍历左边的临时变量
int temp = mid-1;
while (true){
//数组已经越界
if (temp < 0 || arr[temp] != findVal ){
break;
}
temp --;
}
//向右扫面,并且加入,这样,下标就是有序的
temp = temp + 1;
while (true){
if (temp > arr.length-1 || arr[temp] != findVal){
break;
}
resIndexList.add(temp);
temp ++ ;
}
return resIndexList;
}
}
非递归
/**
* 二分查找的非递归算法
* @param arr
* @param low
* @param high
* @param findVal
* @return
*/
public static int binarySearchNotRecursion(int[] arr , int low , int high , int findVal){
while (low < high){
int mid = (low + high ) >>1;
if (findVal > arr[mid]){
low = mid + 1;
}
else if (findVal < arr[mid]){
high = mid -1;
}
else {
return mid;
}
}
//没找到
return -1;
}