//---------------------------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)的更多相关文章

  1. stl源码剖析 详细学习笔记 算法(1)

    //---------------------------15/03/27---------------------------- //算法 { /* 质变算法:会改变操作对象之值 所有的stl算法都 ...

  2. stl源码剖析 详细学习笔记 算法总览

    //****************************基本算法***************************** /* stl算法总览,不在stl标准规格的sgi专属算法,都以 *加以标 ...

  3. stl源码剖析 详细学习笔记 算法(2)

    //---------------------------15/03/29---------------------------- //****************************set相 ...

  4. stl源码剖析 详细学习笔记 算法(4)

    //---------------------------15/03/31---------------------------- //lower_bound(要求有序) template<cl ...

  5. stl源码剖析 详细学习笔记 算法(3)

    //---------------------------15/03/30---------------------------- //min_element template<class Fo ...

  6. stl源码剖析 详细学习笔记 hashtable

    //---------------------------15/03/24---------------------------- //hashtable { /* 概述: sgi采用的是开链法完成h ...

  7. stl源码剖析 详细学习笔记 set map

    // //  set map.cpp //  笔记 // //  Created by fam on 15/3/23. // // //---------------------------15/03 ...

  8. stl源码剖析 详细学习笔记 RB_tree (2)

    //---------------------------15/03/22---------------------------- //一直好奇KeyOfValue是什么,查了下就是一个和仿函数差不多 ...

  9. stl源码剖析 详细学习笔记 RB_tree (1)

    // //  RB_tree_STL.cpp //  笔记 // //  Created by fam on 15/3/21. // // #include "RB_tree_STL.h&q ...

随机推荐

  1. 纯Css实现Div高度根据自适应宽度(百分比)调整

    在如今响应式布局的要求下,很多能自动调整尺寸的元素能够做到高宽自适应,如img,通过{width:50%;height:auto;}实现图片高度跟随宽度比例调整. 然而,用的最多的标签一哥Div却不能 ...

  2. 《SQL Server 2008从入门到精通》--20180723

    目录 1.架构 1.1.创建架构并在架构中创建表 1.2.删除架构 1.3.修改表的架构 2.视图 2.1.新建视图 2.2.使用视图修改数据 2.3.删除视图 3.索引 3.1.聚集索引 3.2.非 ...

  3. 解决:Determining IP Information for eth0...问题

    环境:Centos 6.2     VMWare Workstation 7.1.2  故障现象: 在虚拟机中启动Centos,在启动页面中停留在Determining IP Information ...

  4. 转:js小技巧 ,将彻底屏蔽鼠标右键,可用于Table ,取消选取、防止复制,IE地址栏前换成自己的图标

    1. oncontextmenu="window.event.returnValue=false" 将彻底屏蔽鼠标右键<table border oncontextmenu= ...

  5. 页面中 js,css 集中提取

    新增less的定义: /web/webroot/WEB-INF/_ui-src/responsive/lib/ybase-0.1.0/less/ybase.less ​ css定义: /web/web ...

  6. fedora安装字体

    #fedora安装新字体 将自己现有的字体复制到/usr/share/fonts/自己起个名字/ 例如我要安装下载的苹果苹方字体 #cp 我这个文件夹的地址/* /usr/share/fonts/Pi ...

  7. October 25th, 2017 Week 43rd Wednesday

    Perseverance is not a long race; it is many short races one after another. 坚持不是一个长跑,她是很多一个接一个的短跑. To ...

  8. wx.aui.AuiManager部分/布局翻译

    wx.aui.AuiManager wx.aui.AuiManager 是AUI框架类中的主要类 wx.aui.AuiManager管理于指定的wx.Frame相关联的窗口,通过使用窗口的wx.aui ...

  9. Kafka--基础知识

  10. Mysql千万级数据删除实操-企业案例

    某天,在生产环节中,发现一个定时任务表,由于每次服务区查询这个表就会造成慢查询,给mysql服务器带来不少压力,经过分析,该表中绝对部分数据是垃圾数据 需要删除,约1050万行,由于缺乏处理大数据的额 ...