算法-二分查找

二分查找

二分查找(Binary Search),也称为折半查找,是一种在有序数组中查找特定元素的高效搜索算法。它的核心思想是"分而治之",通过不断将搜索范围缩小一半,从而实现对数级的时间复杂度,使其在处理大规模数据时效率远超线性查找。

使用前提

  • 数据结构必须有序:数组必须是升序或降序排列的。如果数据无序,需要先排序,但这会增加 O(n log n) 的时间开销。
  • 支持随机访问:必须能通过索引在 O(1) 时间内访问任意位置的元素。因此,它非常适合数组,但不适合链表。

复杂度分析

  • 时间复杂度:O(log n)
  • 空间复杂度:O(1)

实现

java 复制代码
public class BinarySearch {
    /**
     * 在有序数组中查找目标值
     * @param nums 已排序的数组(升序)
     * @param target 要查找的目标值
     * @return 目标值的索引,如果不存在则返回 -1
     */
    public static int binarySearch(int[] nums, int target) {
        // 1. 初始化左右指针,定义搜索区间为闭区间 [left, right]
        int left = 0;
        int right = nums.length - 1;

        // 2. 当搜索区间不为空时,持续查找
        // 循环条件是 left <= right,因为当 left == right 时,区间内仍有一个元素需要检查
        while (left <= right) {
            // 3. 计算中间位置
            // 使用 left + (right - left) / 2 而不是 (left + right) / 2,可以防止 (left + right) 过大时发生整数溢出
            int mid = left + (right - left) / 2;

            // 4. 比较中间元素与目标值
            if (nums[mid] == target) {
                // 找到目标值,返回其索引
                return mid;
            } else if (nums[mid] < target) {
                // 目标值在右半区,更新左边界
                // 因为 nums[mid] 已经被检查过且不等于 target,所以新的左边界是 mid + 1
                left = mid + 1;
            } else {
                // 目标值在左半区,更新右边界
                // 同理,新的右边界是 mid - 1
                right = mid - 1;
            }
        }

        // 5. 循环结束仍未找到,返回 -1
        return -1;
    }

    public static void main(String[] args) {
        int[] arr = {2, 4, 7, 10, 15, 18, 21};
        int target = 15;
        int result = binarySearch(arr, target);
        System.out.println("目标值 " + target + " 的索引为: " + result); // 输出: 4
    }
}

优缺点

优点
  • 查找效率极高:O(log n) 的时间复杂度使其在处理大规模数据时优势巨大。
缺点
  • 依赖有序数据:如果数据是无序的,需要先排序,这可能得不偿失。
  • 不适用于频繁增删的数据:数组的插入和删除操作成本较高(O(n)),如果数据集需要频繁变动,维护其有序性的开销会很大。
相关推荐
小羊没烦恼!1 天前
微服务化的基石——持续集成
java·大数据·word·powerpoint·.net
倒头就睡的小比特1 天前
算法竞赛C++常用的STL
c++·算法
俊昭喜喜里1 天前
java中的继承和多态的区别
java
小羊没烦恼!1 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
譕痕1 天前
JSONObject与JSONArray封装数据格式区别
java·json
胡写代码1 天前
别再前后端各写一套表单校验了
java·后端
小鱼能吃糖1 天前
缺陷修复总览 · mall电商项目:5类缺陷,1个病根,4个业务域
java·电商
此时不提桶,更待何时1 天前
01-06-A-JVM排查实战详解
java·jvm
猎头南楼1 天前
知识社区推荐系统实践:新用户冷启动与长短期兴趣建模的挑战 资深推荐算法工程师
人工智能·深度学习·算法·机器学习
vipxieliang1 天前
ValidX 在 DDD 领域驱动设计中的实践
java·spring boot