算法-二分查找

二分查找

二分查找(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)),如果数据集需要频繁变动,维护其有序性的开销会很大。
相关推荐
Flynn Liang4 分钟前
Spring AI 2.0 深度解析:ChatClient、Advisor 链与 MCP——Java 工程师的 AI 落地最优解
java·人工智能·spring·大模型·架构设计·spring ai
灿飞10 分钟前
Kotlin与Java虚拟机六:基础与类型系统:一切皆对象,但对象有代价
java·kotlin
计算机毕设定制辅导-无忧学长19 分钟前
《基于微信小程序健康习惯激励系统设计与实现》
java·spring boot·mysql·微信小程序·uniapp·健康习惯激励系统
小郎君65827 分钟前
Vue 多标签页的加载态设计:为什么我没有用 Suspense 实现 PageLoading
vue.js·算法
JJJennie7771 小时前
MAI Gateway私有化部署全攻略:大模型网关如何接入?附架构图
算法·gateway·ai网关·魔芋ai
東隅已逝,桑榆非晚1 小时前
算法3.双指针法-快乐数
c++·笔记·学习·算法
雪芽蓝域zzs1 小时前
第 1 章:IDEA 创建 SpringBoot3.5.16 Maven 项目
java·maven·intellij-idea
专注仿真1 小时前
卷积神经网络(CNN)算法详解
人工智能·python·算法·代码·大模型训练
FII工业富联科技服务1 小时前
多智能体如何进入制造现场?从业务协同到数字孪生验证
大数据·人工智能·算法·机器人·制造·数字孪生
golang学习记1 小时前
IDEA 开始换芯,发布全新AI版终端
java·人工智能·intellij-idea