首页 > 其他 > 详细

STL源码剖析之【二分查找】

时间:2015-06-09 17:25:32      阅读:249      评论:0      收藏:0      [点我收藏+]

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的源码

template <class _ForwardIter, class _Tp, class _Distance>
_ForwardIter __lower_bound(_ForwardIter __first, _ForwardIter __last,
                           const _Tp& __val, _Distance*) 
{
  _Distance __len = 0;
  distance(__first, __last, __len);
  _Distance __half;
  _ForwardIter __middle;

  while (__len > 0) {
    __half = __len >> 1;
    __middle = __first;
    advance(__middle, __half);
    if (*__middle < __val) {
      __first = __middle;
      ++__first;
      __len = __len - __half - 1;
    }
    else
      __len = __half;
  }
  return __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源码效果一样,在OJ平台测试过)

int Lower_bound(int *a , int n , int value)
{
    int left = 0;
    int right = n-1;

    while(left <= right)
    {
        int mid = (left + right)/2;
        if(a[mid] < value)
        {
            left = mid+1;
        }
        else right = mid -1;
    }

    return left;
}

2: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源码效果一样,在OJ平台测试过)

int Lower_bound(int *a , int n , int value)
{
    int left = 0;
    int right = n-1;

    while(left <= right)
    {
        int mid = (left + right)/2;
        if(a[mid] <= value)
        {
            left = mid+1;
        }
        else right = mid -1;
    }

    return left;
}

3:binary_search()是基于lower_bound的,先找出lower_bound的位置,然后判断该位置是否是我们需要找的目标,返回对比结果


STL源码剖析之【二分查找】

原文:http://blog.csdn.net/u013445530/article/details/46426809

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!