二分查找算法
一、介绍与说明
例子说明:请对一个有序数组进行二分查找 {1,8, 9,10,20, 89, 1000, 1234,2414} ,输入一个数看看该数组是否存在此数,并且求出下标,如果没有就提示"没有这个数"。
通常对于查找某个数在,数组中的位置时,我们会直接遍历整个数组,对其一一比较,最终获得我们的想要查找数的指定位置。但是这种方式太过于消耗内存,特别是当数组的数据特别大的时候,其效果就显得更加的差劲了。
基于对于查找一个数在某个数组的指定位置的目的,我们采取了二分查找算法。
二、思路说明
二分查找算法的思路便是,首先设置最左与最右的数的下标,其次通过引用一个中间变量作为比较对象,当所查找数小于中间数时,便向左查找,最右数的下标变成中间数-1;若所查找数大于中间数时,向右查找,最左数变成中间数+1.一直循环判断,直到找到对应的数,或者当最左数大于等于最右数时,结束循环,返回查询数不存在。
例子:a[8]={1,8, 9,10,20, 89, 1000, 1234,2414} ,在数组查找1000
1 | 8 | 9 | 10 | 20 | 89 | 1000 | 1234 | 2414 |
---|---|---|---|---|---|---|---|---|
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
第一步:设置left为最左的数的下标,设置right为最右的数,中间数mid
①left=0,right=8,mid=(left+righ)/2=4
②进行判断:1000>a[mid]–>1000>a[4]–>1000>20
③所查找数大于中间数,所以我们需要向右查找,因为中间数不可能是所查找数了,所以我们查找的数应该从中间数+1个的位置开始。
④left=mid+1—>left=5;
第二步:
①left=5,right=8,mid=(left+righ)/2=6 // 这里我们取整是向下取整
②进行判断:1000=a[mid]–>1000=a[6]–>1000=1000
③接着我们便直接返回对应的数的下标,即1000的下标6.
三、代码
1)递归方式
/**
*
* @param arr 所查数组
* @param left 最左下标
* @param right 最右下标
* @param findVal 所查数
* @return
*/
public static int binarySeach(int[] arr,int left,int right,int findVal) {
if(left>right) { //当最左数大于最右数时,说明数组已经循环完毕,所查找数,不存在
return -1;
}
int mid=(left+right)/2;
int midVal=arr[mid];
if(findVal>midVal) { //当所查找数大于中间数时,向右查找,最左数为中间数+1
return binarySeach(arr, mid+1, right, findVal);
}else if(findVal<midVal) { //当所查找数小于中间数时,向左查找,最右数为中间数-1
return binarySeach(arr, left, mid-1, findVal);
}else { // 当中间数等于查找数时,返回所查找数下标
return mid;
}
}
2)非递归方式
/**
* 查找某个数在指定数组中的位置
* @param arr 数组
* @param target 需查找的数
* @return
*/
public static int binarySearch(int[] arr,int target) {
// 最左的位置
int left=0;
// 最右的位置
int right=arr.length-1;
while(left<=right) {
// 中间数
int mid=(left+right)/2;
if(arr[mid]==target) {
return mid;
}else if(arr[mid]>target) {
right=mid-1; // 向左查找
}else {
left=mid+1; //向右查找
}
}
return -1;
}
3)测试代码
public static void main(String[] args) {
int[] arr= {1,3,8,10,11,67,100};
// 非递归方式
int index = binarySearch(arr, 11);
System.out.println("index="+index);
// 递归方式
int binarySeach = binarySeach(arr, 0, arr.length, 100);
System.out.println("binarySeach="+binarySeach);
}