本文为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".
}

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

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

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

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

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

  3. STL 源代码剖析 算法 stl_algo.h -- partial_sort / partial_sort_copy

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

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

    本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie lower_bound(应用于有序区间) ------------------------- ...

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

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

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

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

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

    本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie equal_range(应用于有序区间) ------------------------- ...

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

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

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

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

随机推荐

  1. Android中的Layout_weight终极研究

    以前在做UI布局时,也经常用Layout_weight属性,有时会遇到莫名其妙的布局问题,但总没研究懂.一直想做深入分析,但总是没耐心.遇到问题就找替代方法解决,但终非长久之计.这次下决心给它弄透! ...

  2. nyoj 37 回文字符串 【DP】

    先反向复制一个新的字符串,然后再找出最长公共子串,在用长度n减去就可以 回文字符串 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描写叙述 所谓回文字符串,就是一个字符串,从 ...

  3. cocos2dx 关于lua 绑定的环境配置官方文档翻译与 将自己定义c++方法绑定到lua的的方法

    网上有好多写如何讲自己定义的方法绑定到lua的文章,当中都仅仅对环境配置做了简单的介绍,看到有的帖子写在绑定中遇到了各种各样的error.大部分是因为环境配置不对导致的,下面是官方的文档有标准的说明, ...

  4. [Informix] unload load

    select tabname from systables where tabname  like 'aa%' select * from syscolumns where tabname like ...

  5. centos 无法ping内网 Destination Host Unreachable

    centos 突然无法ping内网了. 本来是一直是好好的. 在这之前,当前服务器(centos 192.168.1.30)大量的在操作内网192.168.1.20服务器的数据库.. 会不会是流量大了 ...

  6. Nfs实现linux下文件共享

    前提条件 130是第一台机器,131为第二台机器.都为redhat linux64位系统. 1.      共享要求: 130server上生成的清算文件在131文件夹下能够看得到,131文件夹下生成 ...

  7. HBase源代码分析之HRegionServer上MemStore的flush处理流程(二)

    继上篇文章<HBase源代码分析之HRegionServer上MemStore的flush处理流程(一)>遗留的问题之后,本文我们接着研究HRegionServer上MemStore的fl ...

  8. Java 之进制转换

    //十进制转十六进制 import java.util.Scanner; public class Main{ public static void main(String[] args){ Scan ...

  9. Dubbo源代码实现三:注册中心Registry

    我们知道,对于服务治理框架来说,服务通信(RPC)和服务管理两部分必不可少,而服务管理又分为服务注册.服务发现和服务人工介入,我们来看看Dubbo框架的结构图(来源网络): 图中可以看出,服务提供者P ...

  10. LeetCode -- 推断链表中是否有环

    思路: 使用两个节点.slow和fast,分别行进1步和2步.假设有相交的情况,slow和fast必定相遇:假设没有相交的情况,那么slow或fast必定有一个为null 相遇时有两种可能:1. 仅仅 ...