STL中的二分查找——lower_bound 、upper_bound 、binary_search

STL中的二分查找函数

1、lower_bound函数

在一个非递减序列前闭后开区间[first,last)中,进行二分查找查找某一元素val,函数lower_bound()返回大于或等于val的第一个元素位置(即满足条件a[i]>=val(first<=i<last)的最小的i的值),当区间的所有元素都小于val时,函数返回的i值为last(注意:此时i的值是越界的!!!!!)。

比如:已知数组元素是a[10]={0,2,2,2,6,8,10,16,60,100}

当val=0时,函数lower_bound()返回值为0;

当val=1时,函数lower_bound()返回值为1;

当val=2时,函数lower_bound()返回值为1;

当val=3时,函数lower_bound()返回值为4;

当val=4时,函数lower_bound()返回值为4;

当val=5时,函数lower_bound()返回值为4;

当val=6时,函数lower_bound()返回值为4;

当val=7时,函数lower_bound()返回值为5;

当val=8时,函数lower_bound()返回值为5;

当val=9时,函数lower_bound()返回值为6;

当val=10时,函数lower_bound()返回值为6;

当val=11时,函数lower_bound()返回值为7;

当val=59时,函数lower_bound()返回值为8;

当val=60时,函数lower_bound()返回值为8;

当val=61时,函数lower_bound()返回值为9;

当val=100时,函数lower_bound()返回值为9;

当val=101时,函数lower_bound()返回值为10;

当val=150时,函数lower_bound()返回值为10;

当val=500时,函数lower_bound()返回值为10;

STL中函数lower_bound()的代码实现(first是最终要返回的位置)

int lower_bound(int *array, int size, int key)
{
    int first = 0, middle, 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)中查找
    }
}

vector容器储存序列值时的运行程序:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <sstream>
#include <fstream>
#include <limits.h>
#define debug "output for debug\n"
#define pi (acos(-1.0))
#define eps (1e-4)
#define inf (1<<28)
#define sqr(x) (x) * (x)
#define mod 1e9+7
using namespace std;
typedef long long ll;
typedef unsigned long long ULL;
int main()
{
    int i,x,n,m;
    vector<int> a;

    printf("输入数组长度n(0<n<10000):");
    scanf("%d",&n);

    printf("输入数组的n个元素:");
    for(i=0;i<n;i++)
    {
        scanf("%d",&x);
        a.push_back(x);
    }
    sort(a.begin(),a.end());//排序(非递减序列)

    printf("元素值a[i]/下标i:\n");
    for(i=0;i<n;i++)
        printf("%d/%d\n",a[i],i);

    printf("输入查找的元素m:");
    vector<int>::iterator it;
    while(scanf("%d",&m)!=EOF)
    {
        //vector容器储存序列值时的函数调用方式
        it=lower_bound(a.begin(),a.end(),m);//返回值是迭代器的值
        printf("返回位置对于的值:%d\n",*it);

        printf("输入查找的元素m:");
    }
    return 0;
}

数组储存序列值时的运行程序:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <sstream>
#include <fstream>
#include <limits.h>
#define debug "output for debug\n"
#define pi (acos(-1.0))
#define eps (1e-4)
#define inf (1<<28)
#define sqr(x) (x) * (x)
#define mod 1e9+7
using namespace std;
typedef long long ll;
typedef unsigned long long ULL;
int main()
{
    int i,j,k,n,m,first,last;
    int a[10000];

    printf("输入数组长度n(0<n<10000):");
    scanf("%d",&n);

    printf("输入数组的n个元素:");
    for(i=0;i<n;i++)
        scanf("%d",&a[i]);

    sort(a,a+n);//排序(非递减序列)

    printf("元素值a[i]/下标i:\n");
    for(i=0;i<n;i++)
        printf("%d/%d\n",a[i],i);

    printf("输入区间[first,last)(first<=last<=n):");
    while(scanf("%d%d",&first,&last)!=EOF)
    {
        printf("输入查找的元素m:");
        scanf("%d",&m);
        //数组储存序列值时的函数调用方式
        j=lower_bound(a+first,a+last,m)-a;
        printf("返回位置:%d\n",j);

        printf("输入区间[first,last)(first<=last<=n):");
    }
    return 0;
}

2、upper_bound函数

在一个有序序列(升序或者降序)的区间中,进行二分查找某一元素val,函数upper_bound返回一个迭代器指向该区间中最后一个这个元素的下一个位置(简单的说就是返回能够将元素val插入区间的最后一个位置)。

升序排列的容器:

iterator upper_bound( const key_type &key ):返回一个迭代器,指向键值>key的第一个元素。

降序排列的容器:

iterator upper_bound( const key_type &key ):返回一个迭代器,指向键值<key的第一个元素。

STL中函数upper_bound()的代码实现(first是最终要返回的位置)

int upper_bound(int *array, int size, int key)
{
    int first = 0, len = size-1, 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;
}

数组储存序列值时的运行程序:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <sstream>
#include <fstream>
#include <limits.h>
#define debug "output for debug\n"
#define pi (acos(-1.0))
#define eps (1e-4)
#define inf (1<<28)
#define sqr(x) (x) * (x)
#define mod 1e9+7
using namespace std;
typedef long long ll;
typedef unsigned long long ULL;
int main()
{
    int i,j,k,n,m;
    int a[10000];

    printf("输入数组长度n(0<n<10000):");
    scanf("%d",&n);

    printf("输入数组的n个元素:");
    for(i=0;i<n;i++)
        scanf("%d",&a[i]);

    sort(a,a+n);//排序(非递减序列)

    printf("元素值a[i]/下标i:\n");
    for(i=0;i<n;i++)
        printf("%d/%d\n",a[i],i);

    printf("输入查找的元素m:");
    while(scanf("%d",&m)!=EOF)
    {
        //数组储存序列值时的函数调用方式
        j=upper_bound(a,a+n,m)-a;
        printf("返回位置:%d\n",j);

        printf("输入查找的元素m:");
    }
    return 0;
}

3、binary_search函数

函数binary_search是在有序序列的[first,last)中寻找元素value,若存在就返回true,若不存在则返回false。

程序运行如下:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <sstream>
#include <fstream>
#include <limits.h>
#define debug "output for debug\n"
#define pi (acos(-1.0))
#define eps (1e-4)
#define inf (1<<28)
#define sqr(x) (x) * (x)
#define mod 1e9+7
using namespace std;
typedef long long ll;
typedef unsigned long long ULL;
int main()
{
    int i,j,k,n,m;
    int a[10000];

    printf("输入数组长度n(0<n<10000):");
    scanf("%d",&n);

    printf("输入数组的n个元素:");
    for(i=0;i<n;i++)
        scanf("%d",&a[i]);

    sort(a,a+n);//排序(非递减序列)

    printf("元素值a[i]/下标i:\n");
    for(i=0;i<n;i++)
        printf("%d/%d\n",a[i],i);

    printf("输入查找的元素m:");
    while(scanf("%d",&m)!=EOF)
    {
        //数组储存序列值时的函数调用方式
        j=binary_search(a,a+n,m);//j=upper_bound(a,a+n,m)-a;
        printf("返回位置:%d\n",j);

        printf("输入查找的元素m:");
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-10 12:58:33

STL中的二分查找——lower_bound 、upper_bound 、binary_search的相关文章

STL中的二分查找———lower_bound,upper_bound,binary_search

关于STL中的排序和检索,排序一般用sort函数即可,今天来整理一下检索中常用的函数——lower_bound , upper_bound 和 binary_search . STL中关于二分查找的函数有三个lower_bound .upper_bound .binary_search .这三个函数都运用于有序区间(当然这也是运用二分查找的前提). Tips:1.在检索前,应该用sort函数对数组进行从小到大排序.     2.使用以上函数时必须包含头文件:#include < algorith

STL中的二分查找

本文转载于https://blog.csdn.net/riba2534/article/details/69240450 使用的时候注意:必须用在非递减的区间中 二分查找的原理非常简单,但写出的代码中很容易含有很多Bug,二分查找一文中讲解过如何实现不同类型的二分查找,但是否一定要自己去实现二分查找呢?答案显然是否定的,本文将讲解STL中与二分查找有关函数的具体使用方法及其实现原理. 函数使用 STL中与二分查找相关的函数有4个,分别是lower_bound, upper_bound, equa

C++ STL中的二分查找

这篇博客转自爱国师哥,这里给出连接https://www.cnblogs.com/aiguona/p/7281856.html 一.解释 以前遇到二分的题目都是手动实现二分,不得不说错误比较多,关于返回值,关于区间的左闭右开等很容易出错,最近做题发现直接使用STL中的二分函数方便快捷还不会出错,不过对于没有接触过的同学,二分函数确实是一个头疼的部分,自己查的内容又有点乱,找不到具体的使用方法,有必要自己总结一份完整的以后备用. 二.常用操作 1.头文件 #include <algorithm>

STL 二分查找三兄弟(lower_bound(),upper_bound(),binary_search())

一:起因 (1)STL中关于二分查找的函数有三个:lower_bound .upper_bound .binary_search  -- 这三个函数都运用于有序区间(当然这也是运用二分查找 的前提),下面记录一下这两个函数: (2)ForwardIter lower_bound(ForwardIter first, ForwardIter last,const _Tp& val)算法返回一个非递减序列[first, last)中的第一个大于等于值val的位置: (3)ForwardIter up

算法—8.有序数组中的二分查找

1.具体算法 /** * 算法3.2 二分查找(基于有序数组) * Created by huazhou on 2015/11/29. */ public class BinarySearchST<Key extends Comparable<key>, Value> { private Key[] keys; private Value[] vals; private int N; public BinarySearchST(int capacity){ keys = (Key[

减而治之 - 二分查找 - lower_bound实现原理

本文介绍利用二分实现 lower_bound 的原理. lower_bound(T * a, T & t, int lo, int hi) 的功能是:在某个有序数组 a[lo, hi) 的范围内,查找不小于 t 的最小元素或最小元素位置.这可以用二分来实现. 算法可以这样理解.我们维护两个界限,分别为: L:保证 ≤ L 位置的元素都小于 t:            R:保证 ≥ R 位置的元素都大于等于 t. 我们不断改变 L 和 R 的位置,使 L 和 R 不断靠近,直至 L + 1 = R

有序数组中的二分查找

最近看一些算法题发现这些问题到最后落实到编程实现上都是一种基础的体现,包括对基本的for,if,else,while等语句的理解程度,还有对循环递归的理解.所以还是得回归最基本的算法,现在去学习那些高深复杂的DP,KMP,红黑树未免有点好高骛远.目前应该坚持基础,打好基础,毕竟不是CS科班出身.言归正传,二分查找就是一个最基础的算法.它的时间复杂度O(logn).分为迭代实现和递归实现两种,如下:程序没有经过很多测试,应该有bug,欢迎指正. int BinarySearch(int * a,

STL lower_bound upper_bound binary-search

STL中的二分查找——lower_bound .upper_bound .binary_search 二分查找很简单,原理就不说了.STL中关于二分查找的函数有三个lower_bound .upper_bound .binary_search .这三个函数都运用于有序区间(当然这也是运用二分查找的前提). 其中如果寻找的value存在,那么lower_bound返回一个迭代器指向其中第一个这个元素.upper_bound返回一个迭代器指向其中最后一个这个元素的下一个位置(明确点说就是返回在不破坏

数据结构基础 查找 之 二分查找

[算法思想] 二分查找又称折半查找,对排好序的数组,每次取这个数和数组中间的数进行比较,复杂度是O(logn) 如:设数组为a[n],查找的数x, 如果x==a[n/2],则返回n/2; 如果x < a[n/2],则在a[0]到a[n/2-1]中进行查找: 如果x > a[n/2],则在a[n/2+1]到a[n-1]中进行查找: 优点是比较次数少,查找速度快,平均性能好:其缺点是要求待查表为有序表,且插入删除困难. 条件:查找的数组必须要为有序数组. [递归方法源码] /* arrat:数组