- 二分查找只适用于从有序的数列中进行查找
- 运行时间为对数时间O( log 2 n \log_2{n} log2n), 即最多只需要 log 2 n \log_2{n} log2n步。
- [0,99]中100个数进行查找,需要26<100<27步,最多需要7步
思路:
- 确定出归条件,找到了 或者 start>end
- 找到中间的数,如果比中间数大,则向左找
end = mid-1; - 如果比中间数大,则向右找,知道找到位置;
start = mid +1;
public class erfen {
public int[] arr;
public erfen(int[] arr){
this.arr = arr;
}
// 递归方法
public int searchRec(int start, int end, int target){
int mid = (start+end)/2;
if (target == arr[mid]){
return mid;
}
if (target < arr[(end-start)/2]){
end = mid-1;
if (start>end){return -1;}
return searchRec(start,end,target);
}else{
start = mid+1;
if (start>end){return -1;}
return searchRec(start,end,target);
}
}
// 非递归实现
public int search(int start, int end, int target){
int mid = (start+end)/2;
while(start<=end){
if (target == arr[mid]){
return mid;
}else if (target < arr[(end-start)/2]){
end = mid-1;
mid = (start+end)/2;
}else{
start = mid+1;
mid = (start+end)/2;
}
}
return -1;
}
public static void main(String[] args) {
int[] arr = {1,3, 8, 10, 11, 67, 100};
erfen test = new erfen(arr);
int index1 = test.searchRec(0,arr.length-1,100);
int index2 = test.search(0,arr.length-1,100);
System.out.println("index1=" + index1);//
System.out.println("index2=" + index2);//
}
}
如果数组中含有多个重复数字,上述方法只能实现,找到一个数。如果想找到所有数字,这需要对上述方法进行优化。
思路:
当找到第一个数时,不要进行return,而是将其储存在一个List中,并且对其进行左,右搜索,直到下个数不满足条件,或者index超过引索
public List searchRecPlus(int start, int end, int target){
int mid = (start+end)/2;
if (target == arr[mid]){
List<Integer> resList = new ArrayList<>();
// 向左继续搜索
int temp1 = mid -1 ;
while(temp1>=0 && arr[temp1]==target){
resList.add(temp1);
temp1--;
}
resList.add(mid);
// 向右继续搜索
int temp2 = mid +1 ;
while(temp2<arr.length-1 && arr[temp2]==target){
resList.add(temp2);
temp2++;
}
return resList;
}
if (target < arr[(end-start)/2]){
end = mid-1;
if (start>end){List<Integer> resList = new ArrayList<>();
resList.add(-1);
return resList;}
return searchRecPlus(start,end,target);
}else{
start = mid+1;
if (start>end){List<Integer> resList = new ArrayList<>();
resList.add(-1);
return resList;}
return searchRecPlus(start,end,target);
}
}