lower_bound()与upper_bound()

所在头文件:#include<algorithm>

函数分类:Binary search (operating on partitioned/sorted ranges)

函数功能:lower_bound()返回一个迭代器指针,指向val出现在这个被查找序列中出现的第一个位置;upper_bound()返回一个迭代器指针,指向val出现在这个被查找序列中出现的最后一个位置的后一个位置。

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) { // or: if (comp(*it,val)), for version (2) first=++it; count-=step+1; } else count=step; } return first; }

upper_bound()的函数模板功能相当于:

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))                 // or: if (!comp(val,*it)), for version (2)
    { 
        first=++it; count-=step+1;  
    }
    else count=step;
  }
  return first;
}

lower()返回的是有序数组中第一次出现val的位置,如果找不到,则返回数组的最后一个位置。

upper()返回的是有序数组中最后一次出现val的位置的后一个位置,如果找不到,则返回数组的最后一个位置,如果val与数组最后一个元素相等,则返回数组的最后一个位置。

upper()除了比lower()多了一个 = 以外,其它的地方完全相同。

代码中,array为要查找的数组,b为数组的起始位置,e为数组的结束位置,val为要查找的值,first为指向数组中某个位置的指针,初始化为第一个元素,count为first指针最多能移动的位数,setp为指针需要的位数。

lower()中,当array[it]比val小时,就一直移动first指针,且只向后移动一位(就是这里保证了返回val第一次出现的位置;如果是array[it]等于val,则first指针不会移动,count的值会一直减少,每次减少一半,最终等于0,循环结束然后返回first;如果是array[it]大于val,则first不会移动,count会一直缩减到使得array[it]小于等于val的大小),移动后,更新最多可移动的的位数,这个值为e与first的差,既first的右边部分。
在数组a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}中查找 7
调用lower(a, 0, 9, 7);
first = 0; count = 9;
第一次循环:
it = 0; step = 4; it = 4; a[it] = 5; first = 5; count = 4;

第二次循环:
it = 5; step = 2; it = 7; a[it] = 8; first = 6; count = 1;

第三次循环:
it = 6; step = 0; it = 6; a[it] = 7; count = 0;

找到结束。

#include <bits/stdc++.h>
using namespace std;
int lower(int *array, int b, int e, int val)//二分查找下界
{
    int first = b;
    int count = e - b;
    while (count > 0)
    {
        int it = first;
        int step = count / 2;
        it = it + step;
        if (array[it] < val)
        {
            first = ++it;
            count = count - (step + 1);
        }
        else
        {
            count = step;
        }
    }
    return first;
}

int upper(int *array, int b, int e, int val)//二分查找上界
{
    int first = b;
    int count = e - b;
    while (count > 0)
    {
        int it = first;
        int step = count / 2;
        it = it + step;
        if (array[it] <= val)
        {
            first = ++it;
            count = count - (step + 1);
        }
        else
        {
            count = step;
        }
    }
    return first;
}

int main()
{
    int array[] = {0,1,2,3,4,5,5,5,5,5,6,6,6,7,8,9,10,11,11,11,12,12,13,13};
    int e = sizeof(array) / sizeof(int);
    int ans1 = lower(array, 0, e - 1, 11);
    int ans2 = upper(array, 0, e - 1, 11);
    printf("数组中第一次出现11的位置: %d\n", ans1);
    printf("数组中最后一次出现11的位置的后一个位置: %d\n", ans2);
    printf("------------------------------------------\n");
    int ans3 = lower(array, 0, e - 1, 13);
    int ans4 = upper(array, 0, e - 1, 13);
    printf("数组中第一次出现13的位置: %d\n", ans3);
    printf("数组中最后一次出现13的位置的后一个位置: %d\n", ans4);//此处返回数组的最后一个位置
    printf("------------------------------------------\n");
    int ans5 = lower(array, 0, e - 1, 100);
    int ans6 = upper(array, 0, e - 1, 100);
    printf("找不到 %d,返回数组的最后一个位置\n", ans5);
    printf("找不到 %d,返回数组的最后一个位置\n", ans6);
    printf("-------------\n");
    return 0;
}

你可能感兴趣的:(Algorithm,二分)