本文为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. mini2440裸机试炼之——看门狗中断和复位操作

    看门狗的工作原理: 设本系统程序完整执行一周期的时间是Tp,看门狗的定时周期为Ti,Ti>Tp,在程序正常执行时,定时器就不会溢出,若因为干扰等原因使系统不能在Tp时刻改动定时器的记数值,定时器 ...

  2. js 多选选择删除数据

    按了顶上的删除(多项删除) 单列复选框删除 js语句 <a href="javascript:delOne('${customer.id}')">删除</a> ...

  3. linux 源码安装 Nginx

    1.安装前环境准备安装make:# yum -y install gcc automake autoconf libtool make安装g++:# yum install gcc gcc-c++ 2 ...

  4. MFC的CListCtrl双击获取单元格的行列

    首先要把ClistCtrl设置为整选中模式和网格模式 SetExtendedStyle(LVS_EX_GRIDLINES|LVS_EX_FULLROWSELECT); 重写方法如下: void CAl ...

  5. EF性能

    批量操作时,加上这句:Context.Configuration.AutoDetectChangesEnabled = false; 主要是取消跟踪,缩短对象添加到上下文的时间(非执行SQL的时间)

  6. 什么是Coded UI

    什么是Coded UI Coded UI Test是Visual Studio 2010对于Testing Project(测试工程)提供的关于UI自动化测试的框架,支持Win32,Web,WPF等U ...

  7. spring in action小结2

    1 @Component注解声明的类都会创建为bean,并且bean的id为首字母小写的类名. 2 解决bean自动装配奇异性问题,可以使用@Qualifier("name")限定 ...

  8. vue $http请求服务

    vue中的$http服务  需要引入一个叫vue-resource.js的文件,因为vue.js中没有$http服务.如果需要使用这个服务去百度下载vue-resource.js 然后引进项目即可. ...

  9. RPC服务框架dubbo(四):Dubbo中Provider搭建

    1.新建Maven Project, 里面只有接口(dubbo-service) 1.1 为什么这么做? RPC框架,不希望Consumer知道具体实现.如果实现类和接口在同一个项目中,Consume ...

  10. html5 indexDB的使用

    angular.module('indexdb', []) .factory('indexDbJs', [function() { const CurDBVersion = 10000; window ...