C++二分查找法,upper_bound与lower_bound

该文章已生成可运行项目,

什么是二分查找法

二分查找法(Binary Search)是一种在有序数组中查找特定元素的搜索算法。二分查找法的工作原理是通过不断将搜索区间分成两半来缩小查找的范围,每次比较中间元素与目标值,根据比较结果决定是继续在左半边还是右半边查找。
二分查找法的基本步骤如下:

  1. 首先,确定数组的中间位置。
  2. 比较中间位置的元素与目标值。
  3. 如果中间位置的元素正好是目标值,则搜索过程结束。
  4. 如果目标值小于中间位置的元素,则在数组的左半边继续搜索。
  5. 如果目标值大于中间位置的元素,则在数组的右半边继续搜索。
  6. 重复上述步骤,直到找到目标值或搜索范围为空。
    在 C++ 中,你可以使用标准库中的 std::binary_search 函数来检查数组或容器中是否存在某个元素,或者你可以自己实现二分查找法。以下是使用 std::binary_search 的示例:
#include <iostream>
#include <vector>
#include <algorithm> // 包含 std::binary_search
int main() {
    std::vector<int> vec = {1, 3, 5, 7, 9, 11, 13, 15};
    int target = 7;
    // 使用 std::binary_search 查找元素
    bool found = std::binary_search(vec.begin(), vec.end(), target);
    if (found) {
        std::cout << "Element " << target << " found in the vector." << std::endl;
    } else {
        std::cout << "Element " << target << " not found in the vector." << std::endl;
    }
    return 0;
}

如果你想自己实现二分查找法,以下是代码示例:

#include <iostream>
#include <vector>
int binarySearch(const std::vector<int>& vec, int target) {
    int left = 0;
    int right = vec.size() - 1;
    while (left <= right) {
        int mid = left + (right - left) / 2; // 防止溢出
        if (vec[mid] == target) {
            return mid; // 找到目标值,返回索引
        } else if (vec[mid] < target) {
            left = mid + 1; // 在右侧子数组中查找
        } else {
            right = mid - 1; // 在左侧子数组中查找
        }
    }
    return -1; // 未找到目标值,返回 -1
}
int main() {
    std::vector<int> vec = {1, 3, 5, 7, 9, 11, 13, 15};
    int target = 7;
    int index = binarySearch(vec, target);
    if (index != -1) {
        std::cout << "Element " << target << " found at index " << index << "." << std::endl;
    } else {
        std::cout << "Element " << target << " not found in the vector." << std::endl;
    }
    return 0;
}

在这个示例中,binarySearch 函数实现了二分查找算法,并返回目标值在数组中的索引(如果找到的话),或者返回 -1(如果没有找到)。

什么是upper_bound

upper_bound 是 C++ 标准库中的一个函数,它用于在已排序的序列(例如 std::vectorstd::dequestd::array 或其他支持随机访问迭代器的容器)中查找第一个大于特定值的元素的位置。当你调用 upper_bound 时,它返回一个指向该元素的迭代器,如果不存在这样的元素,则返回指向序列末尾的迭代器(即 end())。
具体来说,upper_bound 的功能如下:

  • 它在指定的迭代器范围 [first, last) 内进行二分查找。
  • 它寻找第一个位置,使得该位置上的元素大于给定的值 value
  • 如果所有元素都不大于 value,则返回 last(一个指向序列末尾的迭代器)。
  • 如果找到了这样的元素,它返回一个指向该元素的迭代器。
    这个函数要求序列在 [first, last) 范围内是有序的,且序列至少部分排序为非降序(即元素可以相等,但不能出现后面的元素小于前面的元素)。
    使用 upper_bound 需要包含 <algorithm> 头文件,并且它通常与 std::sort 或其他排序函数配合使用,以确保序列是有序的。
    在 C++ 中,upper_bound 是标准库中的一个函数,它用于在有序序列中查找第一个大于特定值的元素的位置。该函数定义在头文件 <algorithm> 中。下面是对 upper_bound(a.begin(), a.end(), x) 的详细解释:
  • a.begin(): 这是容器 a 的开始迭代器,指向容器中的第一个元素。
  • a.end(): 这是容器 a 的结束迭代器,指向容器中最后一个元素的下一个位置。
  • x: 这是你要在容器 a 中查找的值。
    函数 upper_bound 的行为如下:
  1. 它在区间 [a.begin(), a.end()) 中查找。
  2. 它寻找第一个位置,使得该位置上的元素大于 x
  3. 如果所有元素都不大于 x,则返回 a.end()
    返回值:
  • 如果找到了这样的元素,upper_bound 返回一个指向该元素的迭代器。
  • 如果没有找到,它返回一个指向 a.end() 的迭代器。
    示例:
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
    std::vector<int> a = {1, 2, 4, 4, 6, 8};
    int x = 4;
    auto it = upper_bound(a.begin(), a.end(), x);
    if (it != a.end()) {
        std::cout << "第一个大于 " << x << " 的元素是:" << *it << std::endl;
    } else {
        std::cout << "没有找到大于 " << x << " 的元素。" << std::endl;
    }
    return 0;
}

在这个例子中,upper_bound 将返回指向第一个 6 的迭代器,因为 6 是第一个大于 4 的元素。如果 x8 或更大的值,upper_bound 将返回 a.end()

lower_bound

C++ 标准库中也有 lower_bound 函数,它与 upper_bound 函数非常相似,但是它们的用途略有不同。lower_bound 用于在已排序的序列中查找第一个不小于(即大于或等于)特定值的元素的位置。
以下是 lower_bound 函数的基本行为:

  • 它在指定的迭代器范围 [first, last) 内进行二分查找。
  • 它寻找第一个位置,使得该位置上的元素不小于给定的值 value
  • 如果所有元素都小于 value,则返回 last(一个指向序列末尾的迭代器)。
  • 如果找到了这样的元素,它返回一个指向该元素的迭代器。
    upper_bound 不同的是,lower_bound 寻找的是第一个大于或等于特定值的元素,而 upper_bound 寻找的是第一个大于特定值的元素。
    lower_bound 的使用也需要包含 <algorithm> 头文件,并且序列必须是有序的。
    下面是 lower_bound 的一个简单示例:
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
    std::vector<int> a = {1, 2, 4, 4, 6, 8};
    int x = 4;
    auto it = lower_bound(a.begin(), a.end(), x);
    if (it != a.end()) {
        std::cout << "第一个大于或等于 " << x << " 的元素是:" << *it << std::endl;
    } else {
        std::cout << "没有找到大于或等于 " << x << " 的元素。" << std::endl;
    }
    return 0;
}

在这个例子中,lower_bound 将返回指向第一个 4 的迭代器,因为 4 是第一个不小于 4 的元素。如果 x1 或更小的值,lower_bound 也将返回指向第一个 1 的迭代器。如果 x9 或更大的值,lower_bound 将返回 a.end()

本文章已经生成可运行项目
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Qhumaing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值