算法-二分查找

二分查找

二分查找(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 后端详解(五):Redis 缓存
java·后端·全栈
黄敬峰2 小时前
深入理解算法核心:从递归思想、数组扁平化到快速排序
算法
plainGeekDev3 小时前
GreenDAO → Room
android·java·kotlin
得物技术3 小时前
从狂野代码到按目标生产:得物推荐 AI Harness 的工程化实践|AICon 演讲整理
人工智能·算法·架构
AI小老六7 小时前
SkillOpt 架构拆解:把 Skill 文本当参数,用执行轨迹训练 Agent
后端·算法·ai编程
胡萝卜术7 小时前
从“分数打架”到“排名投票”:为什么你的ChatBI必须用RRF?
算法·设计模式·面试
亦暖筑序8 小时前
Java 8老系统AI Workflow实战:把一次性AI对话升级成可恢复工作流
java·后端
Asize8 小时前
初识DFS 与 BFS:递归、队列与图遍历
算法
敲代码的彭于晏9 小时前
Bean 生命周期完全图解:前端同学也能看懂的 Spring 核心机制
java·前端·后端
plainGeekDev10 小时前
ButterKnife → ViewBinding
android·java·kotlin