枢纽元选择与算法效率

选择首尾元素做枢纽元

通常的、没有经过充分考虑的选择是将第一个或最后一个元素用作枢纽元。选择第一个元素作为枢纽元的程序例子可以参考专题的前一篇《快速排序里的学问:霍尔快排的实现》,而选择最后一个元素用作枢纽元的程序例子则可以参考《快速排序里的学问:快速排序的过程》这个算法导论里的例子。

选择最后一个元素作为枢纽元的排序过程是这样的:威尼斯人赌场

如果输入是随机的,那么这是可以接受的,但是如果输入是预排序的或者是反序的,那么这样的枢纽元就产生一个劣质的分割,因为所有的元素不是被划入S1就是被划入S2。更有甚者,这种情况发生在所有的递归调用中。

实际上,如果第一个元素用作枢纽元而且输入是预先排序的,那么快速排序所花费的时间将是二次的。然而,预排序的输入(或者有一大段预排序数据的输入)也是相当常见的,因此,使用第一个元素作为枢纽元的算法效率不是很高的。

另一种想法是选取前两个互异的键中的较大者作为枢纽元,但这和只选取第一个元素作为枢纽元效率也差不多。

随机选取枢纽元

一种安全的方针是随机选取枢纽元。

一般来说这种策略非常安全,除非随机数生成器有问题,因为随机的枢纽元不可能总在接连不断地产生劣质的分割。另一方面,随机数的生成一般是昂贵的,根本减少不了算法其余部分的平均运行时间。

三数中分割法

一组N个数的中值是第[N/2]个最大的数。枢纽元的最好的选择是数组的中值。

可是,这很难算出来,并且会明显减慢快速排序的速度。这样的中值的估计可以通过随机选取三个元素并用它们的中值作为枢纽元而得到。事实上,随机性并没有多大的帮助,因此一般的做法是使用左端、右端和中心位置上的三个元素的中值作为枢纽元。显然使用三数中值分割法消除了预排序输入的不好情形。

这种枢纽元选择的的快排,效率可是相当高的。

快速排序还很有很多各种变种,我们这里只研究几个有代表性的算法。

时间: 2024-10-10 02:18:16

枢纽元选择与算法效率的相关文章

快速排序里的学问:枢纽元选择与算法效率

选择首尾元素做枢纽元 通常的.没有经过充分考虑的选择是将第一个或最后一个元素用作枢纽元.选择第一个元素作为枢纽元的程序例子可以参考专题的前一篇<快速排序里的学问:霍尔快排的实现>,而选择最后一个元素用作枢纽元的程序例子则可以参考<快速排序里的学问:快速排序的过程>这个算法导论里的例子. 选择最后一个元素作为枢纽元的排序过程是这样的: 如果输入是随机的,那么这是可以接受的,但是如果输入是预排序的或者是反序的,那么这样的枢纽元就产生一个劣质的分割,因为所有的元素不是被划入S1就是被划入

快速排序中的partition函数的枢纽元选择,代码细节,以及其标准实现

很多笔试面试都喜欢考察快排,叫你手写一个也不是啥事.我很早之前就学了这个,对快速排序的过程是很清楚的.但是最近自己尝试手写,发现之前对算法的细节把握不够精准,很多地方甚至只是大脑中的一个映像,而没有理解其真正的本质意图.于是今天结合了<数据结构>(严蔚敏),和<算法导论>进行一番探究. 首先先给出快速排序的严蔚敏版的实现(实际上这部分的partition也是算法导论里面思考题的实现方式,细节可能不一样): 1 public class QuickSort implements So

快速排序代码(选择最右值最为枢纽元)

        参考了<数据结构域算法分析>书上部分代码,结合自己的理解写出的快速排序程序.书上用三数中值分割法来选择枢纽元,有它的好处,但我觉得使得代码很多地方不够直观.我选择数组的最后一个元素作为枢纽元,然后实现了快排. 关于快排的原理可以去看我博客转载的文章,很直观:点击打开链接 快排的步骤就是: 1.选择枢纽元   2.将小于枢纽元的数放前面,大于枢纽元的数放后面,枢纽元放中间                  3.然后对枢纽元左右两个部分继续进行1和2   下面程序中最主要的是Qui

选择排序算法总结

选择算法 选择算法之选取最大数或最小数 选取最大数或最小数代码实现 选择算法之选取最大数和最小数 选取最大数和最小数代码实现 选取最大数和最小数代码优化 快速选择算法 快速选择算法分析 快速选择算法编码实现 快速选择算法代码优化 BFPRT选择算法 BFPRT选择算法主元选择 BFPRT选择算法性能分析 BFPRT选择算法代码实现 注:本文中的所有代码都在这里 选择算法 选择算法就是用来解决在一堆数里面选出第k大的数的问题.选择算法的设计方法有很多,比如将这堆数据先进行排序,然后取出对应的第k个

【uva 1615】Highway(算法效率--贪心 区间选点问题)

题意:给定平面上N个点和一个值D,要求在x轴上选出尽量少的点,使得对于给定的每个店,都有一个选出的点离它的欧几里德距离不超过D. 解法:先把问题转换成模型,把对平面的点满足条件的点在x轴的直线上可得到一个个区间,这样就是选最小的点覆盖所有的区间的问题了.我之前的一篇博文有较详细的解释:关于贪心算法的经典问题(算法效率 or 动态规划).代码实现我先空着.挖坑~

【排序】选择排序算法

特别说明 对于算法,重在理解其思想.解决问题的方法,思路.因此,以下内容全都假定待排序序列的存储结构为:顺序存储结构. 选择排序思想 选择排序又称为简单选择排序,主要思想描述如下: 01.假设待排序列表为 .选择排序将  划分为由已排序好序的  部分 以及 未排序的  部分: 注意:刚开始时  部分其实可认为只有一个元素,即: 元素 02.每次从  部分中选出最小(或最大)的那个元素,将其放在  的末尾位置: 03.重复02步骤,直到  部分为空为止: 编码参考 简单选择排序是非常简单的一种排序

选择排序算法实现

//选择排序法 //time :2017.3.8 //author :justing_zhang /****************************************************************************************/ #include <stdio.h> void println(int array[], int len){    int i = 0;        for(i=0; i<len; i++)    {     

选择排序算法实现十个1-100的随机数的排序

public class Mian {//对数进行选择排序 public static void selectnumber(int[] number){ for(int i=0;i<number.length-1;i++){ int m=i; for(int j=i+1;j<number.length;j++){ if(number[j]<number[m]){ m=j; } if(i!=m){ swap(number,i,m); } } } } //交换两个数 public stati

数据结构和算法学习总结02 算法效率的度量

算法的效率 我们度量算法效率方式:事前分析估算方法       在计算机程序编写前,依据统计方法对算法进行估算 算法的效率的度量是抽象的,而不是进行精确的测量,忽略硬件方面.程序编译优化,代码循环终止条件和变量声明等因素 下面把函数当成一般的算法进行效率的判断 例子: 函数 n=1 2 3 100 省略后 n+2 3 4 5 102 100 2n+1 3 5 7 201 200 2n+2 4 6 8 202 100 2n^2+2 4 10 20 20002 10000 2n^2+n+2 5 12