stl源码剖析 详细学习笔记 算法(5)
//---------------------------15/04/01----------------------------
//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 =
;
distance(first, middle, len1);
Distance len2 =
;
distance(middle, last, len2);
//用来申请暂时的缓冲区
temporary_buffer<BidirectionalIterator, T> buf(first, last);
)
__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)
{
//先复制[first,middle)区间的元素到缓冲区
Pointer end_buffer = copy(first, middle, buffer);
//调用merge函数,把元素放入first开始的区间,也就是first到last
merge(buffer, end_buffer, middle, last, first);
}
else if(len2 <= buffer_size)
{
Pointer end_buffer = copy(middle, last, buffer);
//从后面开始merge。
__merge_backward(first, middle, buffer, end_buffer, last);
}
else
{
//缓冲区放不下len1
或 len2,需要进行裁剪
//搞不懂为什么前面是lower_bound,后面是upper_bound
//有一种可能是:len1 > len2时,取lower_bound可以使更少的元素换到左边的区间
//len1 < len2时,取upper_bound可以时更少的元素换到右边。
//这么做可以平衡两个区间的元素量
BidirectionalIterator first_cut =first;
BidirectionalIterator second_cut = middle;
Distance len11 =
;
Distance len22 =
;
if(len1 > len2)
{
len11 = len1 /
;
advance(first_cut, len11);
second_cut = lower_bound(middle, last, *first_cut);
distance(middle, second_cut, len22);
}
else
{
len22 = len2 /
;
advance(second_cut, len22);
first_cut = upper_bound(first, middle, *second_cut);
distance(first, first_cut, len11);
}
//到这时区间是这样的 first first_cut middle second_cut last
//为了让为了merge必须让要merge的区间并起来
所以把middle到second_cut,换到first_cut的位置就可以了
//rotate后 first first_cut(原middle) new_middle(原first_cut)
// second_cut(原second_cut) last
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);
}
}
template<class BidirectionalIterator1,
class BidirectionalIterator2,
class Distance>
BidirectionalIterator __rotate_adaptive(BidirectionalIterator1 first,
BidirectionalIterator1 middle,
BidirectionalIterator1 last,
Distance len1, Distance len2,
BidirectionalIterator2 buffer,
Distance buffer_size)
{
//缓冲区足够
就利用缓冲区翻转,不够就调用全局rotate
BidirectionalIterator2 buffer_end;
if(len1 > len2 && len2 <= buffer_size)
{
buffer_end = copy(middle, last, buffer);
copy_backward(first, middle, last);
return copy(buffer, buffer_end, first);
}
else if(len1 <= buffer_size)
{
buffer_end = copy(first, middle, buffer);
copy(middle, last, first);
return copy_backward(buffer, buffer_end, last);
}
else
{
rotate(first, middle, last);
advance(first, len2);
return first;
}
}
//nth_element
//使的nth的元素处在完全排序后的位置,只能保证这一个元素处在对的位置
template<class RandomAccessIterator>
inline void nth_element(RandomAccessIterator first,
RandomAccessIterator nth,
RandomAccessIterator last)
{
__nth_element(first, nth, last, value_type(first));
}
template<class RandomAccessIterator,
class T>
void __nth_element(RandomAccessIterator first,
RandomAccessIterator nth,
RandomAccessIterator last, T*)
{
)
{
//划分一次
RandomAccessIterator cut = __unguarded_partition
(first, last, T(__median(*first,
*(first + (last - first) /
),
*(last -
))));
//nth处在哪边就继续划分那边
if(cut <= nth)
first = cut;
else
last = cut;
}
__insertion_sort(first, last);
}
//merge sort
template<class BidirectionalIterator>
void mergesort(BidirectionalIterator first, BidirectionalIterator last)
{
typename iterator_traits<BidirectionalIterator>::difference_type n
=distance(first, last);
|| n ==
)
return;
else
{
BidirectionalIterator mid = first + n /
;
mergesort(first, mid);
mergesort(mid, last);
inplace_merge(first, mid, last);
}
}
stl源码剖析 详细学习笔记 算法(5)的更多相关文章
- stl源码剖析 详细学习笔记 算法(1)
//---------------------------15/03/27---------------------------- //算法 { /* 质变算法:会改变操作对象之值 所有的stl算法都 ...
- stl源码剖析 详细学习笔记 算法总览
//****************************基本算法***************************** /* stl算法总览,不在stl标准规格的sgi专属算法,都以 *加以标 ...
- stl源码剖析 详细学习笔记 算法(2)
//---------------------------15/03/29---------------------------- //****************************set相 ...
- stl源码剖析 详细学习笔记 算法(4)
//---------------------------15/03/31---------------------------- //lower_bound(要求有序) template<cl ...
- stl源码剖析 详细学习笔记 算法(3)
//---------------------------15/03/30---------------------------- //min_element template<class Fo ...
- stl源码剖析 详细学习笔记 hashtable
//---------------------------15/03/24---------------------------- //hashtable { /* 概述: sgi采用的是开链法完成h ...
- stl源码剖析 详细学习笔记 set map
// // set map.cpp // 笔记 // // Created by fam on 15/3/23. // // //---------------------------15/03 ...
- stl源码剖析 详细学习笔记 RB_tree (2)
//---------------------------15/03/22---------------------------- //一直好奇KeyOfValue是什么,查了下就是一个和仿函数差不多 ...
- stl源码剖析 详细学习笔记 RB_tree (1)
// // RB_tree_STL.cpp // 笔记 // // Created by fam on 15/3/21. // // #include "RB_tree_STL.h&q ...
随机推荐
- C# 实现 JAVA AES加密解密[原创]
以下是网上普遍能收到的JAVA AES加密解密方法. 因为里面用到了KeyGenerator 和 SecureRandom,但是.NET 里面没有这2个类.无法使用安全随机数生成KEY. 我们在接收J ...
- .Net 环境
更多系统版本下载:https://www.microsoft.com/net/download VSCode :https://code.visualstudio.com/
- python基础学习24----使用pymysql连接mysql
使用pymysql连接mysql 安装pymysql pymysql安装可以通过两种方式 使用pip安装 首先简单说一下pip的使用方法 获取帮助 pip --help 升级 pip pip inst ...
- MySQL压缩包zip安装
看了网上好多种教程,自己尝试失败了好多次,最后总算弄好了,具体如下 zip下载地址:https://dev.mysql.com/downloads/mysql/ 之后点击No thanks, just ...
- centos中,tomcat项目创建文件的权限
参考文章:https://cloud.tencent.com/info/5f02caa932fd6dbfc46a3bb01af135e0.html 我们在centos中输入umask,会看到输出002 ...
- Docker容器学习与分享10
Docker容器向外提供服务 用分享04中的Nginx服务来试一下. 不过这次我直接用Nginx镜像创建容器,先下载Nginx镜像. [root@promote ~]# docker search n ...
- C++课堂作业_02_PAT1025.反转链表
The 1st classwork of the C++ program 题目:PAT.1025.反转链表 github链接:Click Here mdzz,做完题目的第一感受= = 这道题的题意就是 ...
- python第三十九课——面向对象(二)之初始化属性
设计Car类,初始化属性speed,提供一个run函数 import time class Car: def __init__(self,speed): self.speed=speed #将Road ...
- loli的搜索测试-5
今天早上听说不放假感觉很sad,又听说要考试感觉更sad了,早读的时候Juan_feng表示即使考也不会考虫食算,结果上午并没有考试,就自己做了几道题.不得不说做题的决定实在是太明智了,做NOIP历年 ...
- AxisWebservice 发送多参数配置
1.在web.xml中配置代码如下 <servlet> <servlet-name>AxisServlet</servlet-name> <display-n ...