二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。
它要求必须是有序数组
首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。
例:在有序数组中查找某个元素的位置:
package PracticeFunction;
//有序数组中查找某个元素的位置
public class BinarySearch {
public static void main(String[] args) {
int[] arr = {1,2,3,4,5,6};
System.out.println(binarySearch(arr,5));
}
static int binarySearch(int[] arr,int target) {
//查找区间开始定义为整个数组,每和中间值比较一次大小,可以缩小一半的查找区间
int min = 0;//min是查找区间最左元素角标,初始为0
int max = arr.length-1;//max是查找区间最右边角标,初始为最大值
int mid = (min+max)>>1;//右移n位相当于除以2的n次方.
while(min<=max) {
if(target<arr[mid]) {
max = mid-1;//若target
}
else if(arr[mid]<target){
min = mid+1;//若arr[mid]
}else {
return mid;//若arr[mid]=target,mid就是a的位置角标
}
mid = (max+min)>>1;
}
return -1;//没有该元素则返回-1
}
}
递归算法有两个特点
public static int binarySearch(int[] arr,int min,int max;int target){
int mid = (min+max)/2;
if(min>max){
return -1;
}else if(target<arr[mid]){
return binarySearch(arr,min,mid-1,target);
}else if(target>arr[mid]){
return binarySearch(arr,mid+1,max,target);
}else{
return mid;
}
}
二分查找法的变例应用:
题目:在有序数组中,若要插入一个数字,使数组仍然有序,求这个数字要插入的位置
解法:只要把上例中的return -1;改成return min即可.
分析:
在上一个例子中,查找过程中[min,max]的区间的两个极值会越来越靠近mid,除非(min+max)/2刚好等于target则结束,返回该值.但是当target不存在时,区间[min,max]会无限靠近target,直到min和max相邻,也就是max=min+1,
比如上例中, 我要查找2.5,
区间会逐渐缩小到[2,3],此时mid=(2+3)/2=2<2.5,
满足条件继续循环,min继续+1,区间变成[3,3],此时mid=3>2.5,则max-1,
此时max
这道题目的解.