STL源码学习----lower_bound和upper_bound算法[转]
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如下图所示:

1, lower_bound
这个序列中可能会有很多重复的元素,也可能所有的元素都相同,为了充分考虑这 种边界条件,STL中的lower_bound算法总体上是才用了二分查找的方法,但是由于是查找序列中的第一个出现的值大于等于val的位置,所以算法 要在二分查找的基础上做一些细微的改动。
首先是我修改数据结构课本上的二分查找实现的lower_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中的实现比较精巧,下面贴出源代码:

//这个算法中,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;
}

2, upper_bound
upper_bound返回的是最后一个大于等于val的位置,也是有一个新元素val进来时的插入位置。
我依然将二分查找略做修改:

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中的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算法
转自:http://www.cnblogs.com/cobbliu/archive/2012/05/21/2512249.html 先贴一下自己的二分代码: #include <cstdio&g ...
- [转] STL源码学习----lower_bound和upper_bound算法
http://www.cnblogs.com/cobbliu/archive/2012/05/21/2512249.html PS: lower_bound of value 就是最后一个 < ...
- stl源码学习(版本2.91)--list
stl源码学习(版本2.91)--list 一,阅读list()构造函数的收获 1,默认构造函数的作用和被调用的时机 struct no{ no(int i){} //no(){ // std::co ...
- 【STL源码学习】STL算法学习之二
第一章:前言 学习笔记,记录学习STL算法的一些个人所得,在以后想用的时候可以快速拾起. 第二章:明细 copy 函数原型: template <class InputIterator, cla ...
- 【STL源码学习】std::list类的类型别名分析
有了点模板元编程的traits基础,看STL源码清晰多了,以前看源码的时候总被各种各样的typedef给折腾得看不下去, 将<list>头文件的类继承结构简化如下 #include < ...
- 【STL源码学习】细品vector
第一节:vector简介 vector是一种典型的类模板,使用的时候必须进行实例化. vector的数据存储在数组上,支持随机访问迭代器,支持下标操作[]和at操作,支持手动扩容和自动容量增长. ve ...
- 【STL源码学习】STL算法学习之三
第一章:前言 数量不多,用到的时候会很爽. 第二章:明细 STL算法中的又一个分类:分割:将已有元素按照既定规则分割成两部分. is_partitioned 函数原型: template <c ...
- 【STL源码学习】STL算法学习之一
第一章:引子 STL包含的算法头文件有三个:<algorithm><numeric><functional>,其中最大最常用的是<algorithm>, ...
- 【STL源码学习】STL算法学习之四
排序算法是STL算法中相当常用的一个类别,包括部分排序和全部排序算法,依据效率和应用场景进行选择. 明细: sort 函数原型: template <class RandomAccessIter ...
随机推荐
- Collectl基础
Collectl比nmon更专业和深入的linux性能测试工具 首先是安装 $ sudo apt-get install collectl 直接输入collectl就可以看到数据 默认是CPU,硬盘, ...
- java --- 设计模式 --- 动态代理
Java设计模式——动态代理 java提供了动态代理的对象,本文主要探究它的实现, 动态代理是AOP(面向切面编程, Aspect Oriented Programming)的基础实现方式, 动态代理 ...
- 标准IO
标准IO由ISO C 标准的IO库,它处理了很多底层细节,比如合适的缓冲大小等等,因此更易于使用,但是也引入了一些其他问题. 流向 标准IO使用FILE对象关联流,流可以是面向宽字节的也可以是面向单字 ...
- ubuntu下apt-get update出现hash校验和错误
可能原因 校园网进行网络缓存导致内容滞后. 解决办法 先清除旧的apt-get更新列表 sudo rm -rf /var/lib/apt/lists/* 使用代理服务器或者VPN 重新更新 sudo ...
- cocos2d-js屏幕任何位置点击开始的实现
ctor:function () { this._super(); if ('mouse' in cc.sys.capabilities) cc.eventManager.addListener({ ...
- cocos2d-x使用python创建vs模板
cocos2d-x 2.2推荐使用create_project.py创建工程,所有的平台都可以通过这个python文件创建工程.这个文件位置在源码cocos2d-x-2.2.2\tools\proje ...
- windows下揪出java程序占用cpu很高的线程 并找到问题代码 死循环线程代码
我的一个java程序偶尔会出现cpu占用很高的情况 一直不知道什么原因 今天终于抽时间解决了 系统是win2003 jvisualvm 和 jconsole貌似都只能看到总共占用的cpu 看不到每个线 ...
- A JavaFX based Game Authoring System
http://www.mirkosertic.de/doku.php/javastuff/javafxgameauthoring ——————————————————————————————————— ...
- Python下调用Linux的Shell命令
有时候难免需要直接调用Shell命令来完成一些比较简单的操作,比如mount一个文件系统之类的.那么我们使用Python如何调用Linux的Shell命令?下面来介绍几种常用的方法: 1. os 模块 ...
- “IPSec 共享密钥”丢失。
“IPSec 共享密钥”丢失.请验证您的设置并尝试重新连接. 但是这个vpn原来使用时不需要配置 共享的密钥,而且我也没有这个共享的密钥, 搜了下Mac OSX可以修改配置来绕过它. 在/etc/pp ...