归并排序的STL源码浅析(富帅版)

本文详细探讨了STL归并排序的源码实现,包括inplace_merge、merge_without_buffer、merge_adaptive等关键函数的工作原理,以及如何根据不同情况调用合适的STL函数。同时对比了自定义实现与STL版本的优劣,强调了空间消耗与效率的权衡。文章旨在提升读者对STL排序算法的理解和实践能力。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

归并排序的STL源码浅析(富帅版)

 

        在之前的归并排序C++实现中,已经给出了我自己写的代码。当然了,与STL版本所考虑的,以及所设计的完整性与安全性,仍然有不小差距。在这些源码中,inplace_merge适用于已序区间。将两个连接在一起的序列[first,middle)和[middle,last)都已排序,并仍然保持排序的特性。如果原先两个序列是递增的,执行结果也递增;如果两个序列递减,执行结果也递减。inplace_merge,merge_without_buffer和merge_adaptive都有两个版本——第一版本默认operator<,第二版本用指定的Functor(comp)进行比较。由于两个版本只有符号方面有区别,而其他绝大部分如出一辙。所以这里主要讨论operator<的版本。

        首先看看主函数inplace_merge:

         inplace_merge先判断两个之前已排序的序列(requires_sorted)是否为空,只要有任何一个序列为空,就什么都没必要再做下去。如果两个序列都不为空,就计算两序列的长度len1和len2,以及配置临时缓冲区Temporary_buffer;如果配置成功,则将两段序列及序列长度送入merge_adaptive中,也就是缓冲区足够大的情况;如果失败,就送入merge_without_buffer中,即使缓冲区不足,也能运作,就是效率不太高。

 

        接着看看辅助函数merge_without_buffer(缓冲区空间不足时)的分配方案:

        在缓冲区不足的情况下,就需要紧缩银根过日子。对两个序列的拆分也需要精打细算。取两个变量len11和len22作为对两个子序列再进行递归拆分后的长度。 两个子序列中,取更长的一段一分为二,而first_cut和second_cut为在不破坏序列顺序的情况下,可插入的最后一个合适的位置。在找到拆分位置后,仍需要调用rotate算法。最后就对子序列再次进行递归拆分,继续无缓冲区的一分为二,直至最后获得的两序列为空,或者两序列只有最后两个元素,就能比较大小并结束递归了。

 

        然后看看辅助函数merge_adaptive(缓冲区足够的情况下)的分配方案:

          在缓冲区足够的情况下,就应该充分利用空间,提高效率。对两个序列的拆分就可以大方一些。当有缓冲区的时候,仍需要缓冲区的大小是否足以安置序列。如果缓冲区足够安置某一段序列,直接利用merge或merge_adaptive来复制到缓冲区中,再将两区间合并,形成一个有序的区间;如果确实有缓冲区空间,但不足以安置任何一个序列,就需要调用rotate_adaptive版本,来对递归拆分之后原长度一半的序列进行尝试,看看更小的序列能否容纳于缓冲区中。        

         接着看看辅助函数rotate_adaptive:

        rotate_adaptive与rotate基本没有什么不同,都用来处理两序列间元素互换。只是rotate_adaptive有了缓冲区的襄助,可以利用move3以及move_backward3移动到一小段缓冲区中,但如果缓冲区依然不足,就只能调用rotate算法,没有缓冲区的版本了。 

 

 

        参考归并排序的C++实现(大众版),可发现,STL版本的归并排序,在架构方面,按照各种不同的情况调用合理的STL函数,并利用Bidirectional Iterator作为默认迭代器;尤其针对缓冲区的空间大小不同情况,处理了好几种可能并实现出来。这么做就比我自己写的版本更加完善和安全。

        归并排序要提高效率,就不可避免地需要消耗更多的空间和临时内存,而且也要花费将数据复制到缓冲区再复制回来等附加工作;尽管归并排序很容易理解,并且比较次数很少,但由于消耗空间大,很难用于主存排序。而在平常的排序工作中,主要应用快速排序解决问题。有关快速排序的问题,后续博文会详细说明。

 

 

        本博文的写作目的是更好地掌握归并排序以及初涉与归并排序相关的STL源代码相关心得体会,若各位优快云er需要掌握更多,请参阅《STL源码剖析》。

 

 

 

参考文献及链接:

1.《STL源码剖析》侯捷著
2.《数据结构与算法分析 C++描述》 第3版  Mark Allen Weiss著,张怀勇等译
3.《C++标准模板库 -自修教程及参考手册-》  Nicolai M.Josuttis著,侯捷/孟岩译

4.http://blog.youkuaiyun.com/mourinho_my_idol/article/details/12426467

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值