二分查找可用于对有序的数列进行查找
二分查找思路:
- 规定要查找的值k可能在数组arr内下标啊i,j
- 计算区间啊i,j的中间点m若k<arr[m],将区间缩小为i,m,继续二分查找
- 若k>arr[m],将区间缩小为m,j继续二分查找
- 若k==arr[m],则找到元素位于位置m
二分查找代码
package BinartSearch;
public class BinarySearch {
public int binarySearch(int[] arr ,int k) {
int i=0;
int j=arr.length;
while(i<j) {
int m =i+(j-i)/2;//int m =(i+j)/2;可能导致溢出
if(k<arr[m]) {
j=m;
}
else if (k>arr[m]) {
i=m+1;
}
else {
return m;
}
}
return -1;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
BinarySearch Binary =new BinarySearch();
System.out.println(Binary.binarySearch(new int[] {1,2,3,4,5}, 1));
System.out.println(Binary.binarySearch(new int[] {1}, 1));
System.out.println(Binary.binarySearch(new int[] {}, 1));
System.out.println(Binary.binarySearch(new int[] {1,2}, 1));
System.out.println(Binary.binarySearch(new int[] {1,2}, 2));
}
}
分析
程序代码使用[i,j),半开半闭区间的好处
- [a,b)+[b,c)=[a,c]
- b-a=len([a,b))
- [a-a)==>empty range
取中值使用到int m =i+(j-i)/2而不使用int m =(i+j)/2,是因为当i、j很大的时候会使得i+j溢出
总结
二分查找的实现总体来说比较好理解,但要注意两个方面,一个边界值,另一个是测试用例的选取。