`
kofsky
  • 浏览: 201720 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类
最新评论

[转载]关于快排的优化

阅读更多
快速排序算法是一种基于分治技术的重要的排序算法,自从它被发明以来,就受到了研究人员的广泛注意。多年以来,人们对这个基本算法进行了大量的改良。我搜集并查阅了一些相关的资料,在下文中对这些改进做出一些介绍。

一、基本的快速排序算法
快速排序算法是由C.A.R. Hoare在1961年发明的一种内排序算法,其大致思想如下[5]:
首先,在要排序的序列a中选取一个中轴值,而后将a分区成为两个部分,左边的部分b中的元素均小于或者等于中轴值,右边的部分c的元素均大于或等于中轴值(分)。而后通过递归调用快速排序的过程分别对这两个部分进行排序(治)。最后将这两部分产生的结果合并即可得到最后的排序序列(合)。
给n个数进行排序时,它平均要做出Θ(nlogn)次的比较,而在最坏的情况下则需要 Θ(n^2)次比较。不过一般来说,在实际上,快速排序算法要显著的快于其他的Θ(nlogn)的算法,主要是由于其内层循环在大多数设计中都能够很有效的实现,并且这一算法可以根据实际的数据在设计上做出改进以使得最坏情况发生的概率尽量减小。[3]

二、快速排序算法的几种改进
1. 三平均分区法[1][9]
关于这一改进的最简单的描述大概是这样的:与一般的快速排序方法不同,它并不是选择待排数组的第一个数作为中轴,而是选用待排数组最左边、最右边和最中间的三个元素的中间值作为中轴。这一改进对于原来的快速排序算法来说,主要有两点优势[1]:
(1) 首先,它使得最坏情况发生的几率减小了。
(2) 其次,未改进的快速排序算法为了防止比较时数组越界,在最后要设置一个哨点。如果在分区排序时,中间的这个元素(也即中轴)是与最右边数过来第二个元素进行交换的话,那么就可以省略与这一哨点值的比较。
关于这一改进还有不同的说法,或者说关于这一改进还有更进一步的改进,在继续的改进中不仅仅是为了选择更好的中轴才进行左中右三个元素的的比较,它同时将这三个数排好序后按照其顺序放回待排数组,这样就能够保证一个长度为n的待排数组在分区之后最长的子分区的长度为n-2,而不是原来的n-1。通过这一技巧,能使得算法的运行时间减少5%左右[9]。
对于三平均分区法还可以进一步扩展,在选取中轴值时,可以从由左中右三个中选取扩大到五个元素中或者更多元素中选取,一般的,会有(2t+1)平均分区法(median-of-(2t+1),三平均分区法英文为median-of-three)。在 [9]中有对(2t+1)平均分区法改进的详细分析,不过文章比较长,读起来也比较困难,所以我就看了个开头。里面对三平均分区法也做了详细的分析,并做出了理论的一个估算,其平均复杂度为,小于上面所说的一般的快速排序算法的平均复杂度 [9]。

2. 根据分区大小调整算法[7][8]
这一方面的改进是针对快速排序算法的弱点进行的。快速排序对于小规模的数据集性能不是很好。可能有人认为可以忽略这个缺点不计,因为大多数排序都只要考虑大规模的适应性就行了。但是快速排序算法使用了分治技术,最终来说大的数据集都要分为小的数据集来进行处理。由此可以得到的改进就是,当数据集较小时,不必继续递归调用快速排序算法,而改为调用其他的对于小规模数据集处理能力较强的排序算法来完成。[7] Introsort就是这样的一种算法,它开始采用快速排序算法进行排序,当递归达到一定深度时就改为堆排序来处理。这样就克服了快速排序在小规模数据集处理中复杂的中轴选择,也确保了堆排序在最坏情况下O(n log n)的复杂度。[8]
另一种优化改进是当分区的规模达到一定小时,便停止快速排序算法。也即快速排序算法的最终产物是一个“几乎”排序完成的有序数列。数列中有部分元素并没有排到最终的有序序列的位置上,但是这种元素并不多。可以对这种“几乎”完成排序的数列使用插入排序算法进行排序以最终完成整个排序过程。因为插入排序对于这种“几乎”完成的排序数列有着接近线性的复杂度。这一改进被证明比持续使用快速排序算法要有效的多。
另一种快速排序的改进策略是在递归排序子分区的时候,总是选择优先排序那个最小的分区。这个选择能够更加有效的利用存储空间从而从整体上加速算法的执行。[7]

3. 不同的分区方案考虑[8]
对于快速排序算法来说,实际上大量的时间都消耗在了分区上面,因此一个好的分区实现是非常重要的。尤其是当要分区的所有的元素值都相等是,一般的快速排序算法就陷入了最坏的一种情况,也即反复的交换相同的元素并返回最差的中轴值。无论是任何数据集,只要它们中包含了很多相同的元素的话,这都是一个严重的问题,因为许多“底层”的分区都会变得完全一样。
对于这种情况的一种改进办法就是将分区分为三块而不是原来的两块:一块是小于中轴值的所有元素,一块是等于中轴值的所有元素,另一块是大于中轴值的所有元素。另一种简单的改进方法是,当分区完成后,如果发现最左和最右两个元素值相等的话就避免递归调用而采用其他的排序算法来完成。

4. 并行的快速排序[4][6]
由于快速排序算法是采用分治技术来进行实现的,这就使得它很容易能够在多台处理机上并行处理。
在大多数情况下,创建一个线程所需要的时间要远远大于两个元素比较和交换的时间,因此,快速排序的并行算法不可能为每个分区都创建一个新的线程。一般来说,会在实现代码中设定一个阀值,如果分区的元素数目多于该阀值的话,就创建一个新的线程来处理这个分区的排序,否则的话就进行递归调用来排序。[4] [6]

对于这一并行快速排序算法也有其改进。该算法的主要问题在于,分区的这一步骤总是要在子序列并行处理之前完成,这就限制了整个算法的并行程度。解决方法就是将分区这一步骤也并行处理。改进后的并行快速排序算法使用2n个指针来并行处理分区这一步骤,从而增加算法的并行程度。

三、总结
总的来说,对于快速排序算法的改进主要集中在三个方面[1]:
1 选取一个更好的中轴值
2 根据产生的子分区大小调整算法
3 不同的划分分区的方法
本文中主要介绍了其中的前两个方面,而第三个方面由于我没有找到足够的相关的资料所以介绍的较为简略。另外本文还加入了并行的快速算法的介绍,从另一个方面来介绍一下对于快速排序算法的可能的改进。

四、参考文献
[1] Roger L. Wainwright. Quicksort Algorithms with an early exit for sorted subfiles, 1987
[2] Anany Levitin 著, 潘彦 译. 算法设计与分析基础, 2004
[3] Quicksort from Wikipedia. http://en.wikipedia.org/wiki/Quick_sort
[4] Parallel Quicksort. http://www.osys.se/Archive/Papers/parallel-sort/node3.html
[5] Quicksort. http://www.iti.fh-flensburg.de/l ... n/quick/quicken.htm
[6] Quicksort or Sample Sort Algorithm. http://www.netlib.org/utk/lsi/pcwLSI/text/node302.html
[7] Quicksort, http://www.fearme.com/misc/alg/node47.html#1242
[8] Quicksort, http://www.absoluteastronomy.com/encyclopedia/Q/Qu/Quicksort.htm
[9] H.-H. Chern and H.-K. Hwang. Transitional Behaviors of the Average Cost of Quick Sort with Median-of-(2t + 1), 2001
分享到:
评论

相关推荐

    秒杀应用的MySQL数据库优化 (转载)

    秒杀应用的MySQL数据库优化是一个重要的议题,尤其是在高并发、数据处理速度要求极高的场景下。这类应用常常面临巨大的压力,如瞬间涌入的大量请求、数据读写速度、以及资源的有效利用。本篇文章将深入探讨如何针对...

    使用gcc和glibc来优化程序 转载.pdf

    这些内置函数能提供与库函数类似的功能,但通常速度更快。 4. **链接时优化(Link-Time Optimization, LTO)** gcc支持链接时优化,允许编译器在所有源文件链接成可执行文件时进行全局优化,进一步提升代码效率。LTO...

    露天煤矿破碎与转载设备方案优化

    在露天采矿中,半连续工艺的破碎与转载系统由不同的设备组成,自移式破碎机是这个系统的重要一环。研究破碎与转载设备的结构形式、几何尺寸与其作业条件的依存关系,并且生产效率、机动灵活性和设备投资及可靠性也是...

    使用gcc和glibc来优化程序 转载.docx

    它们通常比标准库中的函数更快,因为它们可以被编译器更深入地优化,例如,利用向量化(vectorization)技术。 5. **数学运算优化**: 对于数学函数,如平方根、正弦、余弦等,GCC提供了一些内置版本,如`__...

    伊敏露天矿联合作业条件下采排关系优化

    伊敏露天矿联合作业条件下采排关系优化研究涵盖了露天矿开采和排土作业的多个方面,其中包括开采区域的转向、地质构造对开采的影响、东端帮煤炭的开采策略、西端帮排土场空间的扩展以及半连续采煤系统的运用等关键...

    sqlserver数据库优化总结的资料

    在提供的压缩文件中,"SQLSERVER 2005管理与开发 优化SQL Server数据库(转载).mht"可能是关于SQL Server 2005的管理与优化的综合文章,包含了很多实践经验和技巧;"SQL优化.xlsx"可能是对SQL查询优化的实例或数据...

    使用gcc和glibc来优化程序 转载 (2).pdf

    这些内部函数通常比直接调用库函数更快,因为它们避免了函数调用的开销。 4. **其他优化技术** 除了上述方法,还有许多其他优化技术,比如循环展开(Loop Unrolling)、常量折叠(Constant Folding)、分支预测...

    red hat linux安全与优化-转载

    时下安全技术,针对linux系统,探索安全

    使用gcc和glibc来优化程序 转载 (2).docx

    在本文中,我们将探讨如何利用GCC(GNU Compiler Collection)和GLIBC(GNU C Library)来优化C程序,以提高其性能和效率。这主要涉及两个方面:代码优化和利用编译器的特定功能。 首先,代码优化的一个关键点是在...

    桥式转载机转弯装置研究与应用

    综上所述,这篇文章是关于煤矿中桥式转载机转弯装置的研究与应用,涵盖了煤矿生产效率的提升、设备设计优化、工业应用推广等多方面的知识点,同时展示了工程技术分析和仿真工具在现代煤矿设备中的重要作用。

    pso-gru-lstm:PSO优化GRU-LSTM超参数

    PSO优化GRU-LSTM超参数 ...版权声明:本文为CSDN博主「AI信仰者」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_30803353/article/details/126131537

    医疗网站的SEO优化到底该怎么做?(转载).pdf

    SEO(搜索引擎优化)是提升网站在搜索引擎中自然排名的关键手段,尤其对于医疗网站而言,由于行业敏感性和政策限制,SEO优化显得尤为重要。医疗网站的SEO优化主要包括站内优化和站外优化两个方面。 首先,站内优化...

    带式输送机中间转载装置设计研究

    通过详细设计研究,提出了一种新的中间转载装置设计,该设计能够针对该带式输送机的具体工况进行优化,具有重要的工程实践价值。 知识点包括: 1. 带式输送机的工作原理和结构:带式输送机通常由输送带、滚筒、驱动...

    基于Zigbee的地下转载机无线监控网络的设计与优化

    基于zigbee数据帧中的rssi值,本文设计一种通过计算rssi值的强弱来完成对地下转载机位置进行模糊定位。同时结合车载电脑和车载传感器进一步确定转载机姿态。最后通过无线局域网的形式把视频监控数据、远程控制数据、...

    组合优化-算法与理论

    3. 知识产权信息表明,该书的版权属于Springer-Verlag出版社,任何复制、翻译、转载、改编等工作都必须获得出版社的授权。 4. 此书同时也作为高级研究生教材使用,并被设计为研究参考书籍,这暗示了组合优化领域的...

    非线性优化问题求解器ACADO

    ACADO Toolkit 是一个用 C++ ...版权声明:本文为CSDN博主「tzr0725」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/tzr0725/article/details/120632370

Global site tag (gtag.js) - Google Analytics