STL 源代码剖析 算法 stl_algo.h -- inplace_merge

本文为senlie原创。转载请保留此地址:http://blog.csdn.net/zhengsenlie

inplace_merge(应用于有序区间)

--------------------------------------------------------------------

描写叙述:假设两个连接在一起的序列[first, middle)和 [middle, last]都已排序,

那么 inplace_merge 可将它们结合成单一一个序列,并仍有序。

源代码:

template <class BidirectionalIterator>
inline void inplace_merge(BidirectionalIterator first,
                          BidirectionalIterator middle,
                          BidirectionalIterator last) {
  if (first == middle || middle == last) return; //仅仅要有不论什么一个序列为空,就什么都不必做
  __inplace_merge_aux(first, middle, last, value_type(first),
                      distance_type(first));
}

//辅助函数
template <class BidirectionalIterator, class T, class Distance>
inline void __inplace_merge_aux(BidirectionalIterator first,
                                BidirectionalIterator middle,
                                BidirectionalIterator last, T*, Distance*) {
  Distance len1 = 0;
  distance(first, middle, len1);
  Distance len2 = 0;
  distance(middle, last, len2);
  //使用了额外的内存空间(临时缓冲区)
  temporary_buffer<BidirectionalIterator, T> buf(first, last);
  if (buf.begin() == 0) // 内存分配失败
    __merge_without_buffer(first, middle, last, len1, len2);
  else // 在有临时缓冲区的情况下进行
    __merge_adaptive(first, middle, last, len1, len2,
                     buf.begin(), Distance(buf.size()));
}

//辅助函数。有缓冲区的情况下
template <class BidirectionalIterator, class Distance, class Pointer>
void __merge_adaptive(BidirectionalIterator first,
                      BidirectionalIterator middle,
                      BidirectionalIterator last, Distance len1, Distance len2,
                      Pointer buffer, Distance buffer_size) {
  if (len1 <= len2 && len1 <= buffer_size) {
    Pointer end_buffer = copy(first, middle, buffer);
    merge(buffer, end_buffer, middle, last, first);
  }
  else if (len2 <= buffer_size) {
    Pointer end_buffer = copy(middle, last, buffer);
    __merge_backward(first, middle, buffer, end_buffer, last);
  }
  else {
    BidirectionalIterator first_cut = first;
    BidirectionalIterator second_cut = middle;
    Distance len11 = 0;
    Distance len22 = 0;
    if (len1 > len2) {
      len11 = len1 / 2;
      advance(first_cut, len11);
      second_cut = lower_bound(middle, last, *first_cut);
      distance(middle, second_cut, len22);
    }
    else {
      len22 = len2 / 2;
      advance(second_cut, len22);
      first_cut = upper_bound(first, middle, *second_cut);
      distance(first, first_cut, len11);
    }
    BidirectionalIterator new_middle =
      __rotate_adaptive(first_cut, middle, second_cut, len1 - len11,
                        len22, buffer, buffer_size);
    __merge_adaptive(first, first_cut, new_middle, len11, len22, buffer,
                     buffer_size);
    __merge_adaptive(new_middle, second_cut, last, len1 - len11,
                     len2 - len22, buffer, buffer_size);
  }
}

演示样例:

int main()
{
  int A[] = { 1, 3, 5, 7, 2, 4, 6, 8 };

  inplace_merge(A, A + 4, A + 8);
  copy(A, A + 8, ostream_iterator<int>(cout, " "));
  // The output is "1 2 3 4 5 6 7 8".
}
时间: 2024-09-29 02:33:03

STL 源代码剖析 算法 stl_algo.h -- inplace_merge的相关文章

STL 源代码剖析 算法 stl_algo.h -- search

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie search ------------------------------------------------------------------------- 描写叙述:在序列一[first1, last1) 所涵盖的区间中.查找序列二[first2, last2) 的首次出现点. 思路: 1.遍历序列二 2.假设两序列的当前元素一样,都前进 1 3.否则序列二的迭代器又一次指向開始元素

STL 源代码剖析 算法 stl_algo.h -- equal_range

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie equal_range(应用于有序区间) -------------------------------------------------------------------------------------------------------------------------------------- 描写叙述:利用二分查找找到一个区间,区间里的全部值都等于给定值,返回的是一个pa

STL 源代码剖析 算法 stl_algo.h -- lower_bound

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie lower_bound(应用于有序区间) -------------------------------------------------------------------------------------------------------------------------- 描写叙述:二分查找,返回一个迭代器指向每个"不小于 value "的元素, 或 value 应

STL 源代码剖析 算法 stl_algo.h -- rotate

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie rotate -------------------------------------------------------------- 描写叙述:将[first, middle) 内的元素和[middle, last) 内的元素互换. /*------------------------------------------------------------ *分派函数(dispatc

STL 源码剖析 算法 stl_algo.h -- inplace_merge

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie inplace_merge(应用于有序区间) -------------------------------------------------------------------- 描述:如果两个连接在一起的序列[first, middle)和 [middle, last]都已排序, 那么 inplace_merge 可将它们结合成单一一个序列,并仍有序. 源码: template <c

STL 源代码分析 算法 stl_algo.h -- includes

本文senlie原,转载请保留此地址:http://blog.csdn.net/zhengsenlie includes(应用于有序区间) ------------------------------------------------------------- 描写叙述:S1和S2都必须是有序集合.推断序列二 S2 是否"涵盖于"序列一 S1,即"S2的每个元素是否都出现于 S1中" 思路: 1.遍历两个区间.直到当中一个走完 2.假设序列二的元素小于序列一的元素

STL 源代码分析 算法 stl_algo.h -- binary_search

本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie binary_search ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 描

STL 源代码分析 算法 stl_algo.h -- pre_permutation

本文senlie原版的,转载请保留此地址:http://blog.csdn.net/zhengsenlie pre_permutation ---------------------------------------------------------------- 描写叙述: 取得 [first, last) 所标示之序列的前一个排列组合. 假设没有,返回 false,有,返回true 思路: 从后往前 1.找两个相邻元素,令左端的元素为*i,右端的元素为*ii,且满足 *i > *ii 2

STL 源码剖析 算法 stl_algo.h -- merge sort

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie merge sort ---------------------------------------------------------------------- 描述:归并排序 思路: 1.将区间对半分割 2.对左.右段分别排序 3.利用inplace_merge将左.右段合并成为一个完整的有序序列 复杂度:O(nlog n) 源码: template<class Bidirection