📅  最后修改于: 2023-12-03 14:50:52.064000             🧑  作者: Mango
在 C++ 中,有序集是一种特殊的数据结构,它可以存储一组按照某种顺序排列的元素,并提供快速的查找、插入和删除操作。在这篇文章中,我们将介绍如何为有序集实现 upper_bound()
和 lower_bound()
函数,它们可以帮助我们更高效地查找元素。
upper_bound()
是一个函数模板,它接受两个参数 key
和 last
,其中 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()
也是一个函数模板,与 upper_bound()
类似,它接受两个参数 key
和 last
,其中 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) 级别。