为什么要使用二分查找?
在一组数组中如果我们需要快速找到某个元素,通常是使用循环一个一个去确认。所花费的时间是比较多的,如果幸运的话,数组的第一个元素是你需要的。如果不幸的话,你将一个一个查找直到数组的最后个元素。而程序的运行不能单靠运气;
在面试中二分查找也常常出现,如手写程序;
理解二分查找
在使用二分查找时,前提是数组A是有序的。
(1)定义两个变量L(左边界)和R(右边界),确定搜索范围。
(2)定义变量M=(L+R)/2 获取数组中间的索引
(3)用数组中间的索引值A[M]与待搜索的值T进行比较
- A[M]==T 表示找到,返回数组中间的索引
- A[M]>T 则在数组中间右侧的其他元素都大于T,无需比较,中间索引左边去找,M-1设置为右变量,重新查找。
- A[M]<T 则在数组中间左侧的其他元素都小于T,无需比较,中间索引右边去找,M+1设置为左变量,重新查找。
- 如果当L>R时,表示没有找到,应该结束循环。
JAVA实现
package com.ms.jichu;
public class BinarySearch {
public static void main(String[] args) {
int[] array = {1, 5, 8, 11, 19, 22, 31, 35, 40, 45, 48, 49, 50};
int target = 48;//需要找的数
int idx = binarySearch(array, target);
System.out.println("在数组中的索引:" + idx + " 结果array[" + idx + "]" + "=" + array[idx]);
}
//如果找不到,则返回-1
public static int binarySearch(int[] a, int t) {
int l = 0, r = a.length - 1, m;
while (l <= r) {
m = (l + r) / 2;
if (a[m] == t) {
return m;
} else if (a[m] > t) {
r = m - 1;
} else {
l = m + 1;
}
}
return -1;
}
}
解决整数溢出
方法:
(1)将M=(L+R)/2变为M=L+(R-L)/2
析:M=(L+R)/2 》 L/2+R/2 》 L+(-L/2+R/2) 》 L+(R-L)/2
(2)将M=(L+R)/2变为M=(L+R)>>>1; 移位运算,效率其实比方法1除法高。