STL源码学习----lower_bound和upper_bound算法[转]

时间:2022-09-08 18:13:20

  STL中的每个算法都非常精妙,接下来的几天我想集中学习一下STL中的算法。

  ForwardIter lower_bound(ForwardIter first, ForwardIter last,const _Tp& val)算法返回一个非递减序列[first, last)中的第一个大于等于值val的位置。

ForwardIter upper_bound(ForwardIter first, ForwardIter last, const _Tp& val)算法返回一个非递减序列[first, last)中第一个大于val的位置。

lower_bound和upper_bound如下图所示:

STL源码学习----lower_bound和upper_bound算法[转]

1, lower_bound

  这个序列中可能会有很多重复的元素,也可能所有的元素都相同,为了充分考虑这 种边界条件,STL中的lower_bound算法总体上是才用了二分查找的方法,但是由于是查找序列中的第一个出现的值大于等于val的位置,所以算法 要在二分查找的基础上做一些细微的改动。

首先是我修改数据结构课本上的二分查找实现的lower_bound算法:

STL源码学习----lower_bound和upper_bound算法[转]
int my_lower_bound(int *array, int size, int key)
{
int first = 0, last = size-1;
int middle, pos=0; //需要用pos记录第一个大于等于key的元素位置 while(first < last)
{
middle = (first+last)/2;
if(array[middle] < key){ //若中位数的值小于key的值,我们要在右边子序列中查找,这时候pos可能是右边子序列的第一个
first = middle + 1;
pos = first;
}
else{
last = middle; //若中位数的值大于等于key,我们要在左边子序列查找,但有可能middle处就是最终位置,所以我们不移动last,
pos = last; //而是让first不断逼近last。
}
}
return pos;
}
STL源码学习----lower_bound和upper_bound算法[转]

  STL中的实现比较精巧,下面贴出源代码:

STL源码学习----lower_bound和upper_bound算法[转]
//这个算法中,first是最终要返回的位置
int lower_bound(int *array, int size, int key)
{
int first = 0, middle;
int half, len;
len = size; while(len > 0) {
half = len >> 1;
middle = first + half;
if(array[middle] < key) {
first = middle + 1;
len = len-half-1; //在右边子序列中查找
}
else
len = half; //在左边子序列(包含middle)中查找
}
return first;
}
STL源码学习----lower_bound和upper_bound算法[转]

2, upper_bound

upper_bound返回的是最后一个大于等于val的位置,也是有一个新元素val进来时的插入位置。

我依然将二分查找略做修改:

STL源码学习----lower_bound和upper_bound算法[转]
int my_upper_bound(int *array, int size, int key)
{
int first = 0, last = size-1;
int middle, pos = 0; while(first < last)
{
middle = (first+last)/2;
if(array[middle] > key){ //当中位数大于key时,last不动,让first不断逼近last
last = middle;
pos = last;
}
else{
first = middle + 1; //当中位数小于等于key时,将first递增,并记录新的位置
pos = first;
}
}
return pos;
}
STL源码学习----lower_bound和upper_bound算法[转]

下面的代码是STL中的upper_bound实现:

STL源码学习----lower_bound和upper_bound算法[转]
int upper_bound(int *array, int size, int key)
{
int first = 0, len = size-1;
int half, middle; while(len > 0){
half = len >> 1;
middle = first + half;
if(array[middle] > key) //中位数大于key,在包含last的左半边序列中查找。
len = half;
else{
first = middle + 1; //中位数小于等于key,在右半边序列中查找。
len = len - half - 1;
}
}
return first;
}
STL源码学习----lower_bound和upper_bound算法[转]

STL源码学习----lower_bound和upper_bound算法[转]的更多相关文章

  1. STL源码学习----lower&lowbar;bound和upper&lowbar;bound算法

    转自:http://www.cnblogs.com/cobbliu/archive/2012/05/21/2512249.html 先贴一下自己的二分代码: #include <cstdio&g ...

  2. &lbrack;转&rsqb; STL源码学习----lower&lowbar;bound和upper&lowbar;bound算法

    http://www.cnblogs.com/cobbliu/archive/2012/05/21/2512249.html PS: lower_bound of value 就是最后一个 < ...

  3. stl源码学习&lpar;版本2&period;91&rpar;--list

    stl源码学习(版本2.91)--list 一,阅读list()构造函数的收获 1,默认构造函数的作用和被调用的时机 struct no{ no(int i){} //no(){ // std::co ...

  4. 【STL源码学习】STL算法学习之二

    第一章:前言 学习笔记,记录学习STL算法的一些个人所得,在以后想用的时候可以快速拾起. 第二章:明细 copy 函数原型: template <class InputIterator, cla ...

  5. 【STL源码学习】std&colon;&colon;list类的类型别名分析

    有了点模板元编程的traits基础,看STL源码清晰多了,以前看源码的时候总被各种各样的typedef给折腾得看不下去, 将<list>头文件的类继承结构简化如下 #include &lt ...

  6. 【STL源码学习】细品vector

    第一节:vector简介 vector是一种典型的类模板,使用的时候必须进行实例化. vector的数据存储在数组上,支持随机访问迭代器,支持下标操作[]和at操作,支持手动扩容和自动容量增长. ve ...

  7. 【STL源码学习】STL算法学习之三

    第一章:前言 数量不多,用到的时候会很爽. 第二章:明细 STL算法中的又一个分类:分割:将已有元素按照既定规则分割成两部分.  is_partitioned 函数原型: template <c ...

  8. 【STL源码学习】STL算法学习之一

    第一章:引子 STL包含的算法头文件有三个:<algorithm><numeric><functional>,其中最大最常用的是<algorithm>, ...

  9. 【STL源码学习】STL算法学习之四

    排序算法是STL算法中相当常用的一个类别,包括部分排序和全部排序算法,依据效率和应用场景进行选择. 明细: sort 函数原型: template <class RandomAccessIter ...

随机推荐

  1. jquery&period;Callbacks的实现

    前言 本人是一个热爱前端的菜鸟,一直喜欢学习js原生,对于jq这种js库,比较喜欢理解他的实现,虽然自己能力有限,水平很低,但是勉勉强强也算是能够懂一点吧,对于jq源码解读系列,博客园里有很多,推荐大 ...

  2. 重温javascript数据类型

    在javaScript中,有五种简单的数据类型,分别是 Undefined Null Boolean Number String 还有一种复杂的数据类型object,object本质是有一组无序的名值 ...

  3. Spark技术内幕:Master基于ZooKeeper的High Availability(HA)源码实现

    如果Spark的部署方式选择Standalone,一个采用Master/Slaves的典型架构,那么Master是有SPOF(单点故障,Single Point of Failure).Spark可以 ...

  4. 【Linux】Rsync的剖析与使用

    目录 Rsync的工具剖析与使用 0.Rsync的介绍 1.Rsync的特性 2.Rsync的部署安装 3.搭建远程备份系统. Rsync的工具剖析与使用 0.Rsync的介绍 rsync是Linux ...

  5. TZOJ :2731&colon; 存钱计划(二)

    描述 在TZC,WY存了钱,现在他要去买东西了.店很多,标记为1,2,3,4,5,6....但有的店之间有大路相连,而有的没有路.现在要由一个店到另一个店买东西,中途最少要经过多少个其它的店铺呢? 如 ...

  6. Zabbix利用orabbix插件监控Oracle数据库

    一.jdk的安装(Orabbix Server) 1.软件解压,放到固定位置 1 2 tar zxf jdk-8u51-linux-x64.tar.gz mv jdk1.8.0_51/ /usr/lo ...

  7. JS-点和中括号

    今天上午做一个很low的小练习,代码写完了想要封装重复利用来着 可是憋屈啊,怎么都不对,在document.style.width这里,想把width变成参数可是用点的话,会报错说找不到点后边这个属性 ...

  8. AP&ast;更新供应商地点

    --更新供应商地点 PROCEDURE update_vendor_site(p_init_msg_list IN VARCHAR2 DEFAULT fnd_api.g_false, x_return ...

  9. partial分部类

    意义 1.源代码控制 2.将一个类或结构分成不同的逻辑单元 3.代码拆分

  10. python 在线生成文字云

    在线生成文字云 在线生成文字云地址  http://a.leechg.com:8080/wordcloud 效果图 大体步骤 1 接收请求中的文本,通过结巴分词处理文本. seg_generator ...