算法-二分查找

二分查找 (Binary Search)

像“猜数字”游戏一样,每次直接猜正中间的数。如果猜大了,就把右半边的范围全扔掉;如果猜小了,就把左半边的范围全扔掉。通过不断“折半”缩小查找范围,每次都能排除掉一半的数据,从而极其高效地找到目标元素。

核心代码

#include <stdio.h>

// 二分查找函数:在有序数组中查找目标值
int binarySearch(int arr[], int n, int target) {
    int left = 0;          // 左边界指针
    int right = n - 1;     // 右边界指针
    
    // 当左边界小于等于右边界时,说明查找区间依然有效
    while (left <= right) {
        // 计算中间位置(这种写法可防止 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; // 循环结束仍未找到,返回 -1
}

// 打印数组的辅助函数
void printArray(int arr[], int n) {
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

int main() {
    // 注意:二分查找的前提是数组必须有序!
    int arr[] = {12, 22, 25, 34, 64}; 
    int n = sizeof(arr) / sizeof(arr[0]); 
    int target = 25;
    
    printf("数组内容:");
    printArray(arr, n);
    
    int result = binarySearch(arr, n, target); // 调用二分查找
    if (result != -1) {
        printf("目标值 %d 的下标为:%d\n", target, result);
    } else {
        printf("数组中未找到目标值 %d\n", target);
    }
    return 0;
}

示例演示

{12, 22, 25, 34, 64},目标值 target = 25

第 1 次查找:在整体范围 {12, 22, 25, 34, 64} 中查找
目标:通过中间元素判断目标在哪半边。
确定边界:left = 0,right = 4。
计算中点:mid = 0 + (4 - 0) / 2 = 2。中间元素 arr[2] = 25。
比较:25 == 25,命中目标!
第 1 次结束:直接找到目标,返回下标 2。
(为了演示折半过程,我们假设目标值 target = 34)
第 1 次查找:在整体范围 {12, 22, 25, 34, 64} 中查找
确定边界:left = 0,right = 4。
计算中点:mid = 2,中间元素 arr[2] = 25。
比较:25 < 34,说明目标在右侧。更新左边界 left = mid + 1 = 3。
当前查找范围缩小为:[34, 64]

第 2 次查找:在剩余范围 {34, 64} 中查找
确定边界:left = 3,right = 4。
计算中点:mid = 3 + (4 - 3) / 2 = 3。中间元素 arr[3] = 34。
比较:34 == 34,命中目标!
第 2 次结束:找到目标,返回下标 3。

复杂度

时间复杂度是 \(O(logn)\)(每次查找都能排除一半的数据,查找次数随数据规模呈对数级增长)
空间复杂度是 \(O(1)\)(迭代法仅需常数级的额外空间用于维护左右边界和中点指针)

posted @ 2026-07-12 10:06  Eddi^._.^  阅读(8)  评论(0)    收藏  举报