首页 > 代码库 > STL 源码剖析 算法 stl_algo.h -- inplace_merge
STL 源码剖析 算法 stl_algo.h -- inplace_merge
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie
--------------------------------------------------------------------
描述:如果两个连接在一起的序列[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". }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。