C++实现lower_bound、upper_bound函数

本文介绍了C++标准库中的lower_bound和upper_bound函数,这两个函数用于在已排序数组中查找指定值的插入位置,分别返回第一个大于等于和第一个大于指定值的元素位置。作者提供了简单二分查找的源码实现,并通过示例和测试验证了功能正确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

引言

关于这个lower_bound、upper_bound函数我是在学习算法的时候有一个find函数需要去写,然后这个老师就没用库函数,直接写了这个底层实现,然后说这个可以用lower_bound替代,我就想这不就是个简单的二分嘛,然后我就好奇这个函数的底层源码,为此写了这篇博客。

一、库函数介绍

#include <algorithm>  //头文件

首先不论是lower_bound、upper_bound它们提供的数组必须是从小到大有序的,这是作为前提!

1.lower_bound

从左到右查找第一个大于等于 v a l val val 的元素,返回其对应的迭代器

//在 [first, last) 区域内查找不小于 val 的元素
ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last, const T& val);

看一下示例

vector<int> nums{ 1,2,3,4,5,6 };
auto a = lower_bound(nums.begin(), nums.end(), 3);  //返回3所对应的迭代器
cout << *a << endl;  //3

2.upper_bound

从左到右查找第一个大于 v a l val val 的元素,返回其对应的迭代器

//查找[first, last)区域中第一个大于 val 的元素。
ForwardIterator upper_bound (ForwardIterator first, ForwardIterator last, const T& val);

看一下示例

vector<int> nums{ 1,2,3,4,5,6 };
auto a = lower_bound(nums.begin(), nums.end(), 3);  //返回4所对应的迭代器
cout << *a << endl;  //4

二、源码实现

1.lower_bound源码实现

就是一个简单的二分,我就不搞模板了,就能理解底层怎么实现的就行了

int my_lower_bound(const vector<int>& nums, const int& val)
{
	int l = 0, r = nums.size() - 1;
	while (l < r)
	{
		int mid = l + r >> 1;
		if (nums[mid] >= val) r = mid;
		else l = mid + 1;
	}

	return r;
}

2.upper_bound源码实现

int my_upper_bound(const vector<int>& nums, const int& val)
{
	int l = 0, r = nums.size() - 1;
	while (l < r)
	{
		int mid = l + r >> 1;
		if (nums[mid] > val) r = mid;
		else l = mid + 1;
	}

	return r;
}

3.测试

可以看出结果是正确的

int main()
{
	vector<int> nums{ 1,2,3,4,5,6 };

	auto a = my_lower_bound(nums, 3);
	cout << nums[a] << endl;

	a = my_upper_bound(nums, 3);
	cout << nums[a] << endl;

	return 0;
}

在这里插入图片描述

三、全部代码

#include <iostream>
#include <vector>

using namespace std;

int my_lower_bound(const vector<int>& nums, const int& val)
{
	int l = 0, r = nums.size() - 1;
	while (l < r)
	{
		int mid = l + r >> 1;
		if (nums[mid] >= val) r = mid;
		else l = mid + 1;
	}

	return r;
}

int my_upper_bound(const vector<int>& nums, const int& val)
{
	int l = 0, r = nums.size() - 1;
	while (l < r)
	{
		int mid = l + r >> 1;
		if (nums[mid] > val) r = mid;
		else l = mid + 1;
	}

	return r;
}

int main()
{
	vector<int> nums{ 1,2,3,4,5,6 };

	auto a = my_lower_bound(nums, 3);
	cout << nums[a] << endl;

	a = my_upper_bound(nums, 3);
	cout << nums[a] << endl;

	return 0;
}

四、源码

1.lower_bound源码

template <class ForwardIterator, class T>
ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last, const T& val)
{
    ForwardIterator it;
    iterator_traits<ForwardIterator>::difference_type count, step;
    count = distance(first,last);
    while (count>0)
    {
        it = first; step=count/2; advance (it,step);
        if (*it<val) {  //或者 if (comp(*it,val)),对应第 2 种语法格式
            first=++it;
            count-=step+1;
        }
        else count=step;
    }
    return first;
}

2.upper_bound源码

template <class ForwardIterator, class T>
ForwardIterator upper_bound (ForwardIterator first, ForwardIterator last, const T& val)
{
    ForwardIterator it;
    iterator_traits<ForwardIterator>::difference_type count, step;
    count = std::distance(first,last);
    while (count>0)
    {
        it = first; step=count/2; std::advance (it,step);
        if (!(val<*it))  // 或者 if (!comp(val,*it)), 对应第二种语法格式
            { first=++it; count-=step+1;  }
        else count=step;
    }
    return first;
}

五、参考博客

C语言中文网:C++ lower_bound() 函数
C语言中文网:C++ upper_bound() 函数
C++参考手册:std::distance()
CSDN博客:实现lower_bound和upper_bound算法

C++ 中,`lower_bound` 和 `upper_bound` 是 `<algorithm>` 模块提供的两个算法,用于在一个已排序的容器(如向量、列表、集合等)中查找指定元素的位置。这两个函数都是模板函数,可以接受任意类型的比较器(比如默认的 `<` 运算符),以及迭代器作为输入。 1. **lower_bound**: - 函数原型:`template <class _RandomAccessIterator, class _Tp, class _Compare = less<_Tp>> _RandomAccessIterator lower_bound(_RandomAccessIterator first, _RandomAccessIterator last, const _Tp& value, _Compare comp = _Compare());` - 功能:返回一个指向第一个大于等于给定值 `value` 的元素的迭代器,如果序列中不存在这样的元素,则返回 `last`(即序列结尾)。 - 示例: ```cpp std::vector<int> vec = {1, 3, 4, 6, 8}; auto it = std::lower_bound(vec.begin(), vec.end(), 5); // it 现在指向值为 5 或者更大的元素的开始位置 ``` 2. **upper_bound**: - 函数原型:`template <class _RandomAccessIterator, class _Tp, class _Compare = less<_Tp>> _RandomAccessIterator upper_bound(_RandomAccessIterator first, _RandomAccessIterator last, const _Tp& value, _Compare comp = _Compare());` - 功能:返回一个指向第一个大于给定值 `value` 的元素的迭代器,如果序列中不存在这样的元素,则返回 `last + 1`(即序列结束后的下一个位置)。 - 示例: ```cpp std::vector<int> vec = {1, 3, 4, 6, 8}; auto it = std::upper_bound(vec.begin(), vec.end(), 5); // it 现在指向值为 6 或者更大的元素的开始位置 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

lijiachang030718

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

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

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

打赏作者

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

抵扣说明:

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

余额充值