📌  相关文章
📜  在 C++ 中为有序集实现 upper_bound() 和 lower_bound()(1)

📅  最后修改于: 2023-12-03 14:50:52.064000             🧑  作者: Mango

在 C++ 中为有序集实现 upper_bound() 和 lower_bound()

在 C++ 中,有序集是一种特殊的数据结构,它可以存储一组按照某种顺序排列的元素,并提供快速的查找、插入和删除操作。在这篇文章中,我们将介绍如何为有序集实现 upper_bound()lower_bound() 函数,它们可以帮助我们更高效地查找元素。

upper_bound()

upper_bound() 是一个函数模板,它接受两个参数 keylast,其中 key 是要查找的元素值,last 是有序集中最后一个元素的后一个迭代器。upper_bound() 返回一个迭代器,指向有序集中第一个大于 key 的元素。

template<class ForwardIt, class T>
ForwardIt upper_bound(ForwardIt first, ForwardIt last, const T& value)
{
    ForwardIt it = std::lower_bound(first, last, value);
    while (it != last && *it == value) {
        ++it;
    }
    return it;
}

在实现 upper_bound() 的时候,我们可以借助 std::lower_bound() 函数来查找有序集中第一个大于等于 key 的元素,并用一个循环来找到第一个大于 key 的元素。由于 std::lower_bound() 返回的迭代器可能指向最后一个等于 key 的元素,因此需要在循环中加上 *it == value 的判断条件,以避免返回一个相等的迭代器。

lower_bound()

lower_bound() 也是一个函数模板,与 upper_bound() 类似,它接受两个参数 keylast,其中 key 是要查找的元素值,last 是有序集中最后一个元素的后一个迭代器。lower_bound() 返回一个迭代器,指向有序集中第一个大于等于 key 的元素。

template<class ForwardIt, class T>
ForwardIt lower_bound(ForwardIt first, ForwardIt last, const T& value)
{
    while (first != last) {
        ForwardIt mid = std::next(first, std::distance(first, last) / 2);
        if (*mid < value) {
            first = std::next(mid);
        } else {
            last = mid;
        }
    }
    return first;
}

在实现 lower_bound() 的时候,我们可以用二分查找的思想来快速定位有序集中第一个大于等于 key 的元素。具体来说,我们可以先将区间分成两半,然后比较中间元素与 key 的大小关系。如果中间元素小于 key,则说明要查找的元素在右半段,否则在左半段。通过不断缩小区间,直到区间大小为 1,我们就可以找到第一个大于等于 key 的元素。

总结

通过实现 upper_bound()lower_bound() 函数,我们可以更加高效地查找有序集中的元素。在实现过程中,我们借助了 std::lower_bound() 函数和二分查找的思想,使得算法的时间复杂度可以控制在 O(log n) 级别。