binary_search(二分查找)

//版本一:调用operator<进行比较
template <class ForwardIterator,class StrictWeaklyCompareable>
bool binary_search(ForwardIterator first,ForwardIterator last,const StrictWeaklyCompareable &value)
{
ForwardIterator i = lower_bound(first, last, value);
return i != last && !(value < *i);
}
//版本二:调用自己定义的function object
template <class ForwardIterator,class T,class StrictWeaklyCompareable>
bool binary_search(ForwardIterator first,ForwardIterator last,const T& value,StrictWeaklyCompareable cmp);

  若找到值==value的,返回true,否则返回false(if and only if [first,last)中存在一个iterator i,使得*i<value&&vale<*i(cmp(*i,value)和cmp(value,*i))都不成立返回true)

  对于RandomAccessIterator和其他的Iterator复杂度不同,advance对于RandomAccessIterator为常量,对于ForwardIterator为线性

lower_bound

  如果[first,last]中有于value相等的元素,便返回指向第一个元素的迭代器,否则返回指向第一个不小于value的元素。如果大于区间内的所有元素则返回last

//版本一:调用operator<进行比较
template <class ForwardIterator,class StrictWeaklyCompareable>
bool lower_bound(ForwardIterator first,ForwardIterator last,const StrictWeaklyCompareable &value)
{
return __lower_bound(first, last, value,distance_type(first), iterator_category(first));
}
// forward iterator 版本
template <class ForwardIterator, class T, class Distance>
ForwardIterator __lower_bound(ForwardIterator first,ForwardIterator last,const T &value,Distance*,forward_iterator_tag)
{
Distance len = ;
distance(first, last, len);
Distance half;
ForwardIterator middle;
while(len > ) {
half = len >> ;
advance(middle, half); if(*middle < value) {
first = middle;
++first;
len = len - half - ;
} else
len = half;
}
return first;
}
//random access iterator 版本
template <class RandomAccessIterator, class T, class Distance>
RandomAccessIterator __lower_bound(RandomAccessIterator first,RandomAccessIterator last,const T &value,Distance*,random_access_iterator_tag)
{
Distance len = last - first;
Distance half;
RandomAccessIterator middle;
while(len > )
{
half = len >> ;
middle = first + half;
if(*middle < value)
{
first = middle + ;
len = len - half - ;
} else
len = half;
}
return first;
} //版本二:调用自己定义的function object
template <class ForwardIterator,class T,class StrictWeaklyCompareable>
bool lower_bound(ForwardIterator first,ForwardIterator last,const T& value,StrictWeaklyCompareable cmp);

  为二分查找的一种

  1. 若存在,返回的iterator指向第一个值为value的元素
  2. 若不存在,返回第一个不小于value的元素(也即是不破坏元素顺序下第一个可安插value的位置)
  3. 若比range中的所有元素都大,则指向end

upper_bound

  返回在不破坏元素顺序的情况下可插入value的最后一个位置。

//版本一:operator<
template <class BidirectionalIterator>
bool prev_premutation(BidirectionalIterator first,BidirectionalIterator last);
//版本二:用自定义的function object
template <class BidirectionalIterator,class StrictweakOrdering>
bool prev_premutation(BidirectionalIterator first,BidirectionalIterator last,StrictweakOrdering cmo); //版本一:调用operator<进行比较
template <class ForwardIterator,class StrictWeaklyCompareable>
bool upper_bound(ForwardIterator first,ForwardIterator last,const StrictWeaklyCompareable &value)
{
return __upper_bound(first, last, value,distance_type(first), iterator_category(first));
}
// forward iterator 版本
template <class ForwardIterator, class T, class Distance>
ForwardIterator __upper_bound(ForwardIterator first,ForwardIterator last,const T &value,Distance*,forward_iterator_tag)
{
Distance len = ;
distance(first, last, len);
Distance half;
ForwardIterator middle;
while(len > )
{
half = len >> ;
advance(middle, half); if(value < *middle)
len = half;
else {
first = middle;
++first;
len = len - half - ;
}
}
return first;
}
// random access iterator 版本
template <class RandomAccessIterator, class T, class Distance>
RandomAccessIterator __upper_bound(RandomAccessIterator first,RandomAccessIterator last,const T &value,Distance*,random_access_iterator_tag)
{
Distance len = last - first;
Distance half;
RandomAccessIterator middle; while(len > ) {
half = len >> ;
middle = first + half; if(value < *middle)
len = half;
else {
first = middle + ;
len = len - half - ;
}
}
return first;
} //版本二:调用自己定义的function object
template <class ForwardIterator,class T,class StrictWeaklyCompareable>
bool upper_bound(ForwardIterator first,ForwardIterator last,const T& value,StrictWeaklyCompareable cmp);

  为二分查找的一种

  1. 若存在,返回最后一个元素的下一位置
  2. 若不再在,返回最后一个可安插value的位置
  3. 若比range中的所有元素都大,则指向end

equal_range

  返回值是一对i,j,以pair的形式返回,i是第一个可安插value的位置,j是不破坏原来顺序下最后一个可安插的位置,[i,j)中的每个元素都与value相等,所以equal_range的返回值是[first,last)的一个子区间,若range内没有任何一个元素与value等价,返回的是个空range;不破坏原来的range下只有一个位置可安插value,pair的两个元素都指向该位置。

//版本一:由iterator i,j构成的pair,i为[fisrt,last)中最远的iterator,使得[fisrt,i)中每个iterator k都满足*k<=value
//j是[fisrt,last)最远的iterator,使得[fisrt,j)中每个iterator k都满足value<*k不为真,对于[i,j)中每个iterator k,满足value
//<*k和*k<value都不为真
template <class ForwardIterator,class StrictWeaklyCompareable>
pair<ForwardIterator,ForwardIterator> equal_range(ForwardIterator first,ForwardIterator last,const StrictWeaklyCompareable &value)
{
return __equal_range(first, last, value, distance_type(first),iterator_category(first));
}
// ForwardIterator 版本
template <class ForwardIterator, class T, class Distance>
pair<ForwardIterator, ForwardIterator>
__equal_range(ForwardIterator first, ForwardIterator last, const T& value,
Distance*, forward_iterator_tag) {
Distance len = ;
distance(first, last, len);
Distance half;
ForwardIterator middle, left, right;
while (len > ) { // 奇怪? 为什么不直接用 lower_bound 、 upper_bound , 而是等找到值再用?
// --> 我觉得是效率方面的考虑。先找 value ,这时左右两个区间可能已经缩小了许多,
// 再利用 lower_bound 和 upper_bound 代价小很多
half = len >> ;
middle = first;
advance(middle, half);
if (*middle < value) {
first = middle;
++first;
len = len - half - ;
}
else if (value < *middle)
len = half;
else {
left = lower_bound(first, middle, value);
advance(first, len);
right = upper_bound(++middle, first, value);
return pair<ForwardIterator, ForwardIterator>(left, right);
}
}
return pair<ForwardIterator, ForwardIterator>(first, first);
}
// RandomAccessIterator 版本
template <class RandomAccessIterator, class T, class Distance>
pair<RandomAccessIterator, RandomAccessIterator>
__equal_range(RandomAccessIterator first, RandomAccessIterator last,
const T& value, Distance*, random_access_iterator_tag) {
Distance len = last - first;
Distance half;
RandomAccessIterator middle, left, right; while (len > ) {
half = len >> ;
middle = first + half;
if (*middle < value) {
first = middle + ;
len = len - half - ;
}
else if (value < *middle)
len = half;
else {
left = lower_bound(first, middle, value);
right = upper_bound(++middle, first + len, value);
return pair<RandomAccessIterator, RandomAccessIterator>(left,
right);
}
}
return pair<RandomAccessIterator, RandomAccessIterator>(first, first);
}
//版本二:调用自己定义的function object
template <class ForwardIterator,class T,class StrictWeaklyCompareable>
pair<ForwardIterator,ForwardIterator> equal_range(ForwardIterator first,ForwardIterator last,const T& value,StrictWeaklyCompareable cmp);

  

二分查找法(binary_search,lower_bound,upper_bound,equal_range)的更多相关文章

  1. 用c语言编写二分查找法

    二分法的适用范围为有序数列,这方面很有局限性. #include<stdio.h> //二分查找法 void binary_search(int a[],int start,int mid ...

  2. 数据结构和算法:Python实现二分查找(Binary_search)

    在一个列表当中我们可以进行线性查找也可以进行二分查找,即通过不同的方法找到我们想要的数字,线性查找即按照数字从列表里一个一个从左向右查找,找到之后程序停下.而二分查找的效率往往会比线性查找更高. 一. ...

  3. 二分查找法&大O表示法

    二分查找法的输入是一个有序的元素列表,如果要查找的元素包含在列表中,二分查找返回其位置,否则返回null Python代码(来源于<算法图解>一书): def binary_search( ...

  4. 基于Python实现二分查找法实战

    二分查找法实战 def binary_search(datasets, find_in): mid = int(len(datasets)/2) if(mid>0): if(find_in> ...

  5. jvascript 顺序查找和二分查找法

    第一种:顺序查找法 中心思想:和数组中的值逐个比对! /* * 参数说明: * array:传入数组 * findVal:传入需要查找的数 */ function Orderseach(array,f ...

  6. java for循环和数组--冒泡排序、二分查找法

    //100以内与7相关的数   for(int a=1;a<=100;a++){    if(a%7==0||a%10==7||a/10==7){     System.out.print(a+ ...

  7. 二分查找法 java

    前几天去面试,让我写二分查找法,真是哔了狗! 提了离职申请,没事写写吧! 首先二分查找是在一堆有序的序列中找到指定的结果. public class Erfen { public static int ...

  8. 学习练习 java 二分查找法

    package com.hanqi; import java.util.*; public class Test5 { public static void main(String[] args) { ...

  9. Java-数据结构与算法-二分查找法

    1.二分查找法思路:不断缩小范围,直到low <= high 2.代码: package Test; import java.util.Arrays; public class BinarySe ...

随机推荐

  1. `define、parameter、localparam三者的区别(转)

    `define: 可以跨模块的定义,写在模块名称上面,在整个设计工程都有效.一旦‘define指令被编译,其在整个编译过程中都有效.例如,通过另一个文件中的`define指令,定义的常量可以被其他文件 ...

  2. Async注解的使用,异步进行代码解耦

    在开发中进行代码性能的优化方式有很多种,如下单后,要发送消息推送给用户,此时可以使用消息中间件rabbitMq,或者使用异步的方式进行解耦 异步和同步的区别:比如做家务有:做饭,洗衣服,扫地,对于同步 ...

  3. 查看oracle数据库允许的最大连接数和当前连接数

    1.查看当前的数据库连接数  select count(*) from v$process ;    --当前的数据库连接数 2.数据库允许的最大连接数  select value from v$pa ...

  4. ubuntu安装nodejs,npm live-server

    sudo apt-get install curl 先安装的是curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/in ...

  5. http协议tcp协议ip协议三次握手四次挥手,为什么三次握手,为什么四次挥手,sockete套接字理解

    1.1 TCP是什么? TCP是Tranfer Control Protocol的简称,TCP协议是一种面向连接的.可靠的.基于字节流的运输层通信协议.通过TCP协议传输,得到的是一个顺序的无差错的数 ...

  6. linux各种系统下载地址

    1.Arch Linux Arch Linux在安装过程中提供了强大的可定制选择,支持你下载和安装自己所需的程序包.虽然这个选择对新手来说没有多大的帮助,但是它确实能够帮助那些使用Arch构建系统和存 ...

  7. Day11作业及默写

    1.写函数,传入n个数,返回字典{'max':最大值,'min':最小值} 例如:min_max(2,5,7,8,4) 返回:{'max':8,'min':2}(此题用到max(),min()内置函数 ...

  8. Python学习笔记第二十二周(前端知识点补充)

    目录: 一.伪类 二.样式 1.字体 2.背景图片 3.margin和padding 4.列表属性 5.float 6.clear 7.position 8.text-decoration(a标签下划 ...

  9. opengl库学习

    http://www.cppblog.com/doing5552/archive/2009/01/08/71532.html http://blog.csdn.net/wolf96/article/d ...

  10. youtube-dl 使用小记

    0.官网地址 youtube-dl官网:https://yt-dl.org/项目地址:https://github.com/rg3/youtube-dl 1.文档简略翻译,具体请以官方文档为准 Usa ...