C语言:二分搜索函数

一、二分搜索基本概念

二分搜索(Binary Search)是一种在有序数组中查找特定元素的高效算法,时间复杂度为O(log n)。

基本特点:

  • 仅适用于有序数组(升序或降序)

  • 每次比较将搜索范围减半

  • 比线性搜索(O(n))高效得多

二、标准二分搜索实现

1. 迭代版本(最常用)

cpp 复制代码
int binarySearch(int arr[], int size, int target) {
    int left = 0;
    int right = size - 1;
    
    while (left <= right) {
        int mid = left + (right - left) / 2; // 防止溢出
        
        if (arr[mid] == target) {
            return mid; // 找到目标,返回索引
        } else if (arr[mid] < target) {
            left = mid + 1; // 目标在右半部分
        } else {
            right = mid - 1; // 目标在左半部分
        }
    }
    
    return -1; // 未找到
}

2. 递归版本

cpp 复制代码
int binarySearchRecursive(int arr[], int left, int right, int target) {
    if (left > right) {
        return -1;
    }
    
    int mid = left + (right - left) / 2;
    
    if (arr[mid] == target) {
        return mid;
    } else if (arr[mid] < target) {
        return binarySearchRecursive(arr, mid + 1, right, target);
    } else {
        return binarySearchRecursive(arr, left, mid - 1, target);
    }
}

三、二分搜索变种

1. 查找第一个等于目标的值

cpp 复制代码
int findFirst(int arr[], int size, int target) {
    int left = 0;
    int right = size - 1;
    int result = -1;
    
    while (left <= right) {
        int mid = left + (right - left) / 2;
        
        if (arr[mid] == target) {
            result = mid;
            right = mid - 1; // 继续在左半部分查找
        } else if (arr[mid] < target) {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
    
    return result;
}

2. 查找最后一个等于目标的值

cpp 复制代码
int findLast(int arr[], int size, int target) {
    int left = 0;
    int right = size - 1;
    int result = -1;
    
    while (left <= right) {
        int mid = left + (right - left) / 2;
        
        if (arr[mid] == target) {
            result = mid;
            left = mid + 1; // 继续在右半部分查找
        } else if (arr[mid] < target) {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
    
    return result;
}

3. 查找第一个大于等于目标的值

cpp 复制代码
int findFirstGreaterOrEqual(int arr[], int size, int target) {
    int left = 0;
    int right = size - 1;
    int result = -1;
    
    while (left <= right) {
        int mid = left + (right - left) / 2;
        
        if (arr[mid] >= target) {
            result = mid;
            right = mid - 1;
        } else {
            left = mid + 1;
        }
    }
    
    return result;
}

四、注意

1.常见错误

忘记数组必须有序

循环条件错误(应为left <= right而非left < right

边界更新错误(left = mid而非left = mid + 1

整数溢出问题

2.注意事项

  • 数组必须有序:二分搜索的前提条件

  • 整数溢出问题mid = (left + right)/2可能溢出,应使用left + (right-left)/2

  • 边界条件:正确处理left和right的更新

  • 重复元素:标准实现不保证返回哪个匹配项

相关推荐
用户938515635079 小时前
从 O(n²) 到 O(nlogn):一文读懂快速排序的“快”与“妙”
javascript·算法
To_OC10 小时前
手写快排次次翻车?别死背快排模板了,这才是面试官想听的底层逻辑
javascript·算法·排序算法
饼干哥哥11 小时前
Reddit VOC调研太慢?搭一个AI专家团队半小时洞察任何品类|以猫用饮水机为例
人工智能·算法·ai编程
地平线开发者12 小时前
Transformer模型部署之性能优化指南
算法
地平线开发者12 小时前
人在途中:从“编译失败”到“模型可落地”——CUDA 自定义算子
算法·自动驾驶
半个落月15 小时前
从递归到快速排序:用 JavaScript 把分治思想讲明白
javascript·算法·面试
小月土星16 小时前
JavaScript 快速排序:从 pivot、双指针到分治思想
javascript·算法·面试
小月土星16 小时前
JavaScript 递归入门:从 1 到 n 求和,再到数组扁平化
javascript·算法·面试
To_OC1 天前
LC 1 两数之和:面试第一道必考题,暴力解法直接被面试官 pass
javascript·算法·leetcode