一.原理分析
1.使用数组最中间位置的元素值与要查找的指定数值进行比较,若相等,返回中间元素值的索引;
2. 最中间位置的元素值与要查找的指定数值进行比较,若不相等,则根据比较的结果,缩小查询范围为上次数组查询范围的一半;
3. 再根据新的查询范围,更新最中间元素位置,然后使用中间元素值与要查找的指定数值进行比较 ;
比较结果相等,返回中间元素值的索引
比较结果不相等,继续缩小查询范围为上次数组查询范围的一半,更新最中间元素位置,继续比较,依次类推。
当查询范围缩小到小于0个元素时,则指定数值没有查询到,返回索引值-1
二.实现步骤
定义三个变量记录数组索引,变量min记录最小索引,初始值为0,变量max记录最大索引,初始值为数组长度-1,变量mid记录当前范围最中间元素的索引值,初始值为(min+max)/
使用循环,判断当前范围下,最中间元素值与指定查找的数值是否相等
若相等,结束循环,返回当前范围最中间元素的索引值mid
若不相等,根据比较结果,缩小查询范围为上一次查询范围的一般
中间元素值比要查询的数值大,说明要查询的数值在当前范围的最小索引位置与中间索引位置之间,此时,更新查询范围为:
范围最大索引值 = 上一次中间索引位置 -1;
中间元素值比要查询的数值小,说明要查询的数值在当前范围的最大索引位置与中间索引位置之间,此时,更新查询范围为:
范围最小索引值 = 上一次中间索引位置 +1;
在新的查询范围中,更新中间元素值的位置,再次使用最中间元素值与指定查找的数值是否相等。
中间索引值 = (范围最小索引值 +范围最大索引值) / 2;
每次查询范围缩小一半后,使用if语句判断,查询范围是否小于0个元素,若小于0个元素,则说明指定数值没有查询到,返回索引值-1
三.代码
public class Test {
public static void main(String[] args) {
int [] arr = {1,4,7,12,15};
int aim = search (arr, 4);
System.out.println(aim);
}
public static int search (int [] arr,int aim ) {
int min = 0;
int max = arr.length-1;
int mid = 0;
while (min <= max) {
mid = (max+min)/2;
if (aim > arr[mid]) {
min = mid + 1;
}else if (aim < arr[mid]) {
max = mid - 1;
}else {
return mid ;
}
}
return -1;
}
}
三.举例
3.1 例1
给定数组 arr = {1,4,7,12,15}
查询数组元素7的索引
Min =0 max=4 mid=2, 比较目标元素与mid索引上的元素,此时目标元素7=7;
返回结果 mid =2,即要查找的元素索引是2
3.2 例2
查询数组元素4的索引
第一次查找
Min =0 max=4 mid=2,比较目标元素与mid索引上的元素,此时目标元素4<7;
根据规律,将max移动到1索引上
第二次查找
Min =0 max=1注意 (0+1)/2=0.5,这里取mid=0,比较目标元素与mid索引上的元素,此时目标元素4>1;
根据规律,将min移动到1索引上
第三次查找
Min =1 max=1 mid=1,比较目标元素与mid索引上的元素,此时目标元素4=4;
返回结果 mid =1,即要查找的元素索引是1
3.3 例3
给定数组 arr = {1,12,4,7, 15}
查询数组元素4的索引
第一次查找
Min =0 max=4 mid=2,比较目标元素与mid索引上的元素,此时目标元素4<7;
根据规律,我们可以得知此时目标元素应在当前范围的最小索引位置与中间索引位置之间,但是观察素组此范围内并没有目标元素
根据规律,将max移动到1索引上
第二次查找
Min =0 max=1同理舍去,取mid=0,比较目标元素与mid索引上的元素,此时目标元素4>1;
根据规律,将min移动到1索引上
第三次查找
Min =1 max=1 mid=1,比较目标元素与mid索引上的元素,此时目标元素4<12;
根据规律,我们应将min移动到2索引上,mid=1,此时min >max,程序结束,返回值-1,即未找到目标元素,但是此时数组中有目标元素
四.总结
根据例3我们可以得到:要使用二分查找法的前提是数组中的元素必须是有序排列的
结束条件:目标元素=mid索引上的元素
Min > max