携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第8天,点击查看活动详情
前言
基础算法学习,之前学习这些算法也都是学学忘忘,也都没有记录下来,遇到就是百度,正好趁着这个机会每天学习一下,记录下来,和大家分享一下。
坚持,坚持,坚持!!!
二分查找
二分查找的基本思想主要就是将n个元素分成大致相等的两部分,取a[n/2]与x做比较,如果x=a[n/2],则找到x,算法中止;如果x<a[n/2],则只要在数组a的左半部分继续搜索x,如果x>a[n/2],则只要在数组a的右半部搜索x,直到找到对应的数据。
算法描述
-
1.前提:有已排序数组 a(假设已经做好)
-
2.定义左边界 l、右边界 r,确定搜索范围,循环执行二分查找(3、4两步)
-
3.获取中间索引 m = (l + r) / 2
-
4.中间索引的值 a[m] 与目标值 t 进行比较
-
1.a[m] == t 表示找到,返回中间索引
-
2.a[m] > t,中间值右侧的其它元素都大于 t,无需比较,中间索引左边去找,m - 1 设置为右边界,重新查找
-
3.a[m] < t,中间值左侧的其它元素都小于 t,无需比较,中间索引右边去找,m + 1 设置为左边界,重新查找
-
-
5.当 l ≥ r 时,表示没有找到,应结束循环
算法实现
public static int binarySearch(int[] a, int t) {
// 已有排序数据a
// 1.定义左边界l和右边界r以及中间索引m
int l = 0, r = a.length - 1, m;
while (l <= r) {
// 2.获取中间索引m
m = (l + r) / 2;
if (a[m] == t) {
// 3.集合中间索引的值 == 目标值t,直接返回对应索引m
return m;
} else if (a[m] > t) {
// 4.集合中间索引的值 > 目标值t,右边界r缩小,m-1,继续循环查找
r = m - 1;
} else {
// 5.集合中间索引的值 < 目标值t,左边界l扩大,m+1,继续循环查找
l = m + 1;
}
}
// 6.直至左右边界重合查不到目标值后返回-1
return -1;
}
测试代码
public static void main(String[] args) {
int[] array = {1, 3, 8, 11, 20, 35, 40, 47, 48, 49, 60};
int target = 40; // 40, 42
int idx = binarySearch(array, target);
System.out.println(idx);
}
结果
解决整数溢出问题
当 l 和 r 都较大时,l + r 有可能超过整数范围,造成运算错误,解决方法有两种:
int m = l + (r - l) / 2;
还有一种是:
int m = (l + r) >>> 1;
大家多多讨论学习salute