1、什么是二分查找

二分查找又称为折半查找,首先是从有序数组(必须是有序数组)的中间元素开始查找,如果中间元素是查找数,就返回;
如果中间元素大于或者小于查找数,就从大于或小于查找数的一方继续执行二分查找;没找到就返回空,二分查找和传统查找的差别可以看上图
2、二分查找代码思路:
- 确定该数组的中间下标mid
mid=(left+right)/2
- 让待查找数target和arr[mid]比较
- 当target>arr[mid]时,说明查找数在mid右边,继续向右边递归查找
- 当target<arr[mid]时,说明查找数在mid左边,继续向左边递归查找
- 当target==arr[mid]时,说明查找数已经找到,返回
- 比较完后找不到,设置递归退出条件:left>right
3、代码实现:
static List Index=new ArrayList(); //后面查找元素是多个时使用
public static void main(String[] args) {
int arr[]={1,3,5,7,11,11,11,13,17,19,23,29,31,37,41};
Search(arr,0,arr.length-1,11);
System.out.println(Index);
}
当查找数是单个时:
public static int Search(int[] arr,int left,int right,int target){
//退出条件,因为最差的就是只剩下一个数(left==right),当left>right时,说明已经把数组查找完了
if (left>right){
return -1;
}
int mid=(left+right)/2;
if (arr[mid]>target){ //查找数小于arr[mid],左遍历
return Search(arr,left,mid-1,target);
} else if (arr[mid]<target){//查找数大于arr[mid],右遍历
return Search(arr,mid+1,right,target);
}else {//找到后返回
return mid;
}
}
当查找数是多个时:
法一:
if (arr[mid]>target){ //查找数小于arr[mid],左遍历
return Search(arr,left,mid-1,target);
} else if (arr[mid]<target){//查找数大于arr[mid],右遍历
return Search(arr,mid+1,right,target);
}else {//找到后返回
Index.add(mid); //先添加找到的这个数
int temp=mid-1;
while (true){ //向左循环遍历查找
if (temp<0 || arr[temp]!=target){
break;
}
Index.add(temp);
temp-=1;
}
temp=mid+1;
while (true){ //向右循环遍历查找
if (temp>arr.length-1 || arr[temp]!=target){
break;
}
Index.add(temp);
temp+=1;
}
return mid;
}
法一查找多个用了while循环查找,有人觉得会很繁琐,其实未必,因为有序数组的相同元素是挨着的,如
int arr[]={1,3,5,7,11,11,11,13,17,19,23,29,31,37,41};
法二:
else {//找到后返回
Index.add(mid);
Search(arr,left,mid-1,target);
Search(arr,mid+1,right,target);
return mid;
}
4、二分查找的缺陷
- 数组必须时有序的
- 查找的必须时数组