c++二分详解

这里有一道简单到爆的题:

从1-n个数中找到k这个数的下标(这个数组已经排好序了,且这个数组从下标1开始)。

很简单

int n, k;
cin >> n >> k;
for(int i=1;i<=n;i++)
{
    int a;
    cin >> a;
    if(a == k)
    {
        cout << i << endl;
    }
}
return 0;
//时间复杂度O(n)

但有没有更快的算法呢?

二分啦!!!

这个算法就是一半,一半,一半,一半,一半,一半,一半,一半,一半……

int low = 1, high = n;
while (low <= high)
{  
    int mid = low + (high - low) / 2; 
    if (arr[mid - 1] == k)
    {
        cout << mid << endl;
        return 0;
    } 
    else if (arr[mid - 1] < k)
    {  
        low = mid + 1;  
    }
    else
    {  
        high = mid - 1;  
    }  
}
cout << -1 << endl;
return 0;

这是一个模版,必须要背下来哦。

正文

二分查找(Binary Search)是一种在有序数组中查找某一特定元素的搜索算法。二分查找的基本思想是:通过不断将数组分成两半,判断目标值可能存在的区间,逐步缩小搜索范围,直到找到目标值或搜索范围为空。二分查找的时间复杂度为O(log n),其中n是数组的长度。

二分查找的前提

  • 数组必须是有序的(升序或降序)。

二分查找的基本步骤

  1. 确定搜索范围:初始化两个指针leftright,分别指向数组的第一个元素和最后一个元素的索引。
  2. 循环判断:当left <= right时,执行循环。
  3. 计算中间索引:通过(left + right) / 2(left + right) >> 1(位运算,效率更高)计算中间索引mid
  4. 判断中间元素:将中间元素与目标值进行比较。
    • 如果中间元素正好是要找的元素,则搜索成功,返回该元素的索引。
    • 如果中间元素大于目标值,则目标值只可能出现在左半部分,因此将right更新为mid - 1
    • 如果中间元素小于目标值,则目标值只可能出现在右半部分,因此将left更新为mid + 1
  5. 循环结束:如果循环结束还没有找到目标值,则说明数组中不存在该元素,返回特定值(如-1)表示未找到
#include <iostream>  
#include <vector>  
  
using namespace std;  
  
int binarySearch(const vector<int>& nums, int target) {  
    int low = 0, high = nums.size() - 1;  
    while (low <= high) {  
        int mid = low + (high - low) / 2; // 防止溢出  
        if (nums[mid] == target) {  
            return mid; // 找到目标值,返回索引  
        } else if (nums[mid] < target) {  
            low = mid + 1; // 调整左边界  
        } else {  
            high = mid - 1; // 调整右边界  
        }  
    }  
    return -1; // 未找到目标值,返回-1或其他错误码  
}  
  
int main() {  
    vector<int> nums = {1, 2, 4, 5, 6, 8, 9};  
    int target = 5;  
    int result = binarySearch(nums, target);  
    if (result != -1) {  
        cout << "元素找到,索引为:" << result << endl;  
    } else {  
        cout << "元素未找到" << endl;  
    }  
    return 0;  
}

注意事项

  1. 数组必须是有序的:二分查找的前提是数组已经排序。
  2. 整数溢出:在计算中间位置mid时,要注意整数溢出问题,可以使用mid = low + (high - low) / 2来避免。
  3. 边界条件:在更新lowhigh时,要注意是否应该包含边界值,即使用<=还是<
  4. 返回值:如果未找到目标值,需要有一个明确的返回值来表示搜索失败。
  5. 数组为空或仅有一个元素:这些特殊情况需要单独处理,但上述代码已经隐含地处理了这些情况(当low > high时,返回-1)。

二分查找是一种非常高效的搜索算法,特别是在处理大数据集时,其性能优势尤为明显。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值