手写二分查找
1.什么是二分查找
从有序的数组中,先查最中间的数k,和要找的数a进行比较,如果k<a,则对k右边在进行二分查找直到找到位置,反之对左边进行二分查找
2.编写二分查找的代码
- 前提:要有一个排好序的数组A
- 定义左右边界,左边界L,右边界R,确定搜索范围,循环执行二分查找
- 获取中间的索引值M = Floor((L+R)/2)
- floor向下取整
- 中间索引的值与带搜索的值T进行比较
- 如果A[M] == T,表示找到,并且返回 中间索引M
- 如果A[M]>T,中间值偏右的其他元素都>T,无需比较,从中间索引左边去找,M-1设置位右边界,重新查找
- 如果A[M]<T,中间值偏左的其他元素的<T,无需比较,从中间索引的右边去找,M+1设置位左边界,重新查找
- 当L>R时,表示没有找到,结束循环
import static java.lang.Math.floor;
public class BinarySearch {
public static void main(String[] args) {
//一个排序好的数组 array[]
int[] array = {1,5,8,11,19,22,31,35,40,45,48,49,50};
//目标数 target = 40
int target = 48;
//得到target的下标,如果未找到返回-1
int index = binarySearch(array, target);
System.out.println(index);
}
//使用当数组过大时会产出溢出问题
public static int binarySearch0(int[] a,int target){
//left 为左边界,right 为右边界
int left = 0;
//注意 右边界应当为长度 -1
int right = a.length-1;
int m;
while (left<=right){
m = (left + right) / 2;
if (a[m] == target){
return m;
}else if (a[m]<target){
left = m + 1;
}else if (a[m]>target){
right = m -1;
}
}
return -1;
}
//方法一:m=(l+r)/2 => m=2/l+r/2 ===> m=l+(r-l)/2
public static int binarySearch1(int[] a,int target){
//left 为左边界,right 为右边界
int left = 0;
//注意 右边界应当为长度 -1
int right = a.length-1;
int m;
while (left<=right){
m = left + (right - left) / 2;
if (a[m] == target){
return m;
}else if (a[m]<target){
left = m + 1;
}else if (a[m]>target){
right = m -1;
}
}
return -1;
}
//方法二:使用无符号的右移 m = (left + right) >>> 1;
public static int binarySearch(int[] a,int target){
//left 为左边界,right 为右边界
int left = 0;
//注意 右边界应当为长度 -1
int right = a.length-1;
int m;
while (left<=right){
m = (left + right) >>> 1;
if (a[m] == target){
return m;
}else if (a[m]<target){
left = m + 1;
}else if (a[m]>target){
right = m -1;
}
}
return -1;
}
}
ps:
- 要注意初始右边界是 数组的长度 -1
- 比较的时候,使用索引的值去比较
- 总体循环 满足 left<=right下去找
- m 的赋值 优先考虑使用 >>>1