排序集锦(各种排序算法的特点及性能分析)

关于排序,似乎很简单的很常见的概念,却蕴含着很多技术,下面是从不同的角度,对排序的总结:

直插希
冒泡快
选择堆

1 按照排序特性分类

首先按照排序本身的操作特性可以分为下面几种:

 插入排序
直接插入排序(Insert Sort) O(n^2)(稳定)
折半插入排序(Binary Insert Sort)(不稳定)
希尔排序(Shell Sort)(不稳定)

交换排序
冒泡排序(Bubble Sort) O(n^2)(稳定)
快速排序(Quick Sort)?? O(nlogn)(不稳定)

选择排序
直接选择排序(Select Sort) O(n^2)(不稳定)
锦标赛排序(Tournament Sort) O(nlogn)(不稳定)
堆排序(Heap Sort) O(nlogn)(不稳定)

 归并排序(Merge Sort) O(nlogn)
稳定,还取决与,每段的排序算法选择。比如每段长度大于2 用稳定的直接插入排序,然后再归并,不一定要到长度为2 的粒度再归并。


 基数排序(Radix Sort) O(d(n+radix))(稳定性 待定)

2 每种排序算法的特点:

冒泡排序:在最优情况下只需要经过n- 1次比较即可得出结果,(这个最优情况那就是序列己是正序,从100K的正序结果可以看出结果正是如此),但在最坏情况下,即倒序(或一个较小值在最 后),下沉算法将需要n(n-1)/2次比较。所以一般情况下,特别是在逆序时,它很不理想。它是对数据有序性非常敏感的排序算法。

 

冒泡排序2:它是冒泡排序的改良(一次下沉再一次上浮),最优情况和最坏情况与冒泡排序差不多,但是一般情况下它要好过冒泡排序,它一次下沉,再一次上浮,这样避免了因一个数的逆序,而造成巨大的比较。如(2,3,4,…,n- 1,n,1),用冒泡排序需要n(n-1)/2次比较,而此排序只要3轮,共比较(n-1)+(n-2)+(n-3)次,第一轮1将上移一位,第二轮1将 移到首位,第三轮将发现无数据交换,序列有序而结束。但它同样是一个对数据有序性非常敏感的排序算法,只适合于数据基本有序的排序。

 

快速排序:它同样是冒泡排序的改进,它通过一次交换能消除多个逆序,这样可以减少逆序时所消耗的扫描和数据交换次数。在最优情况下,它的排序时间复杂度为O(nlog2n)。 即每次划分序列时,能均匀分成两个子串。但最差情况下它的时间复杂度将是O(n^2)。即每次划分子串时,一串为空,另一串为m-1(程序中的100K正 序和逆序就正是这样,如果程序中采用每次取序列中部数据作为划分点,那将在正序和逆时达到最优)。从100K中正序的结果上看“快速排序”会比“冒泡排 序”更慢,这主要是“冒泡排序”中采用了提前结束排序的方法。有的书上这解释“快速排序”,在理论上讲,如果每次能均匀划分序列,它将是最快的排序算法, 因此称它作快速排序。虽然很难均匀划分序列,但就平均性能而言,它仍是基于关键字比较的内部排序算法中速度最快者。

 

直接选择排序:简单的选择排序,它的比较次数一定:n(n- 1)/2。也因此无论在序列何种情况下,它都不会有优秀的表现(从上100K的正序和反序数据可以发现它耗时相差不多,相差的只是数据移动时间),可见对 数据的有序性不敏感。它虽然比较次数多,但它的数据交换量却很少。所以我们将发现它在一般情况下将快于冒泡排序。

 

堆排序:由于它在直接选择排序的基础上利用了比较结果形成。效率提高很大。它完成排序的总比较次数为O(nlog2n)。它是对数据的有序性不敏感的一种算法。但堆排序将需要做两个步骤:-是建堆,二是排序(调整堆)。所以一般在小规模的序列中不合适,但对于较大的序列,将表现出优越的性能。

 

直接插入排序:简 单的插入排序,每次比较后最多移掉一个逆序,因此与冒泡排序的效率相同。但它在速度上还是要高点,这是因为在冒泡排序下是进行值交换,而在插入排序下是值 移动,所以直接插入排序将要优于冒泡排序。直接插入法也是一种对数据的有序性非常敏感的一种算法。在有序情况下只需要经过n-1次比较,在最坏情况下,将需要n(n-1)/2次比较。

 

希尔排序:增量的选择将影响希尔排序的效率。但是无论怎样选择增量,最后一定要使增量为1,进行一次直接插入排序。但它相对于直接插入排序,由于在子表中每进行一次比较,就可能移去整个经性表中的多个逆序,从而改善了整个排序性能。希尔排序算是一种基于插入排序的算法,所以对数据有序敏感。

 

归并排序:归并排序是一种非就地排序,将需要与待排序序列一样多的辅助空间。在使用它对两个己有序的序列归并,将有无比的优势。其时间复杂度无论是在最好情况下还是在最坏情况下均是O(nlog2n)。对数据的有序性不敏感。若数据节点数据量大,那将不适合。但可改造成索引操作,效果将非常出色。

      基数排序:在程序中采用的是以数值的十进制位分解,然后对空间采用一次性分配,因此它需要较多的辅助空间(10*n+10), (但我们可以进行其它分解,如以一个字节分解,空间采用链表将只需辅助空间n+256)。基数排序的时间是线性的(即O(n))。由此可见,基数排序非常吸引人,但它也不是就地排序,若节点数据量大时宜改为索引排序。但基数排序有个前提,要关键字能象整型、字符串这样能分解,若是浮点型那就不行了。

总结 各种排序方法比较

     简单排序中直接插入最好,快速排序最快,当文件为正序时,直接插入和冒泡均最佳。

3. 按平均时间将排序分为四类



(1)平方阶(O(n2))排序
     一般称为简单排序,例如直接插入、直接选择和冒泡排序;

(2)线性对数阶(O(nlgn))排序
     如快速、堆和归并排序;

(3)O(n1+£)阶排序
     £是介于0和1之间的常数,即0<£<1,如希尔排序;

(4)线性阶(O(n))排序
     如桶、箱和基数排序。
 



4. 影响排序效果的因素



     因为不同的排序方法适应不同的应用环境和要求,所以选择合适的排序方法应综合考虑下列因素:
  ①待排序的记录数目n;
  ②记录的大小(规模);
  ③关键字的结构及其初始状态;
  ④对稳定性的要求;
  ⑤语言工具的条件;
  ⑥存储结构;
  ⑦时间和辅助空间复杂度等。


5 .不同条件下,排序方法的选择


(1)若n较小(如n≤50),可采用直接插入或直接选择排序。
     当记录规模较小时,直接插入排序较好;否则因为直接选择移动的记录数少于直接插人,应选直接选择排序为宜。
(2)若文件初始状态基本有序(指正序),则应选用直接插人、冒泡或随机的快速排序为宜;
(3)若n较大,则应采用时间复杂度为O(nlgn)的排序方法:快速排序、堆排序或归并排序。
     快速排序是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短;
     堆排序所需的辅助空间少于快速排序,并且不会出现快速排序可能出现的最坏情况。这两种排序都是不稳定的。
     若要求排序稳定,则可选用归并排序。但本章介绍的从单个记录起进行两两归并的  排序算法并不值得提倡,通常可以将它和直接插入排序结合在一起使用。先利用直接插入排序求得较长的有序子文件,然后再两两归并之。因为直接插入排序是稳定 的,所以改进后的归并排序仍是稳定的。

6.排序算法的稳定性

 1) 稳定的:如果存在多个具有相同排序码的记录,经过排序后,这些记录的相对次序仍然保持不变,则这种排序算法称为稳定的。
    插入排序、冒泡排序、归并排序、分配排序(桶式、基数)都是稳定的排序算法。
    2)不稳定的:否则称为不稳定的。
    直接选择排序、堆排序、shell排序、快速排序都是不稳定的排序算法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/439856.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【CodeForces - 689D】Friends and Subsequences(RMQ,二分 或单调队列)

题干&#xff1a; Mike and !Mike are old childhood rivals, they are opposite in everything they do, except programming. Today they have a problem they cannot solve on their own, but together (with you) — who knows? Every one of them has an integer seque…

6.深度学习练习:Initialization

本文节选自吴恩达老师《深度学习专项课程》编程作业&#xff0c;在此表示感谢。 课程链接&#xff1a;https://www.deeplearning.ai/deep-learning-specialization/ 目录 1 - Neural Network model 2 - Zero initialization 3 - Random initialization&#xff08;掌握&…

Java Object类的各个方法

Java中所有的类都继承自java.lang.Object类&#xff0c;Object类中一共有11个方法&#xff1a; public final native Class<?> getClass();public native int hashCode();public boolean equals(Object obj) {return (this obj); }protected native Object clone() th…

【CodeForces - 602D】Lipshitz Sequence(思维,单调栈,斜率单调性)

题干&#xff1a; A function is called Lipschitz continuous if there is a real constant Ksuch that the inequality |f(x) - f(y)| ≤ K|x - y| holds for all . Well deal with a more... discrete version of this term. For an array , we define its Lipschi…

7.深度学习练习:Regularization

本文节选自吴恩达老师《深度学习专项课程》编程作业&#xff0c;在此表示感谢。 课程链接&#xff1a;https://www.deeplearning.ai/deep-learning-specialization/ 目录 1-Package 2 - Non-regularized model 3 - L2 Regularization&#xff08;掌握&#xff09; 4-Dropou…

深入详解JVM内存模型与JVM参数详细配置

本系列会持续更新。 JVM基本是BAT面试必考的内容&#xff0c;今天我们先从JVM内存模型开启详解整个JVM系列&#xff0c;希望看完整个系列后&#xff0c;可以轻松通过BAT关于JVM的考核。 BAT必考JVM系列专题 1.JVM内存模型 2.JVM垃圾回收算法 3.JVM垃圾回收器 4.JVM参数详解 5…

【2019牛客暑期多校训练营(第三场)- A】Graph Games(思维,对边分块)

题干&#xff1a; 链接&#xff1a;https://ac.nowcoder.com/acm/contest/883/A 来源&#xff1a;牛客网 You are given an undirected graph with N\ N N vertices and M\ M M edges. The edges are numbered from 1\ 1 1 to M\ M M . Denote the set S(x)\ S(x) S…

8.深度学习练习:Gradient Checking

本文节选自吴恩达老师《深度学习专项课程》编程作业&#xff0c;在此表示感谢。 课程链接&#xff1a;https://www.deeplearning.ai/deep-learning-specialization/ 目录 1) How does gradient checking work? 2) 1-dimensional gradient checking 3) N-dimensional gradie…

苹果手机看电流判断故障

正常的开机电流 1、按开机键后电流在40mA摆动一下&#xff08;CPU供电正常&#xff09;&#xff1b; 2、到80mA左右摆动一下&#xff08;暂存开始工作&#xff0c;也就是CPU上盖&#xff0c;然后开始进行总线的初始化&#xff09;&#xff1b; 3、指针到120mA左右摆动&#xff…

【CodeForces - 675C】Money Transfers(思维,前缀和)

题干&#xff1a; There are n banks in the city where Vasya lives, they are located in a circle, such that any two banks are neighbouring if their indices differ by no more than 1. Also, bank 1 and bank n are neighbours if n > 1. No bank is a neighbou…

9.深度学习练习:Optimization Methods

本文节选自吴恩达老师《深度学习专项课程》编程作业&#xff0c;在此表示感谢。 课程链接&#xff1a;https://www.deeplearning.ai/deep-learning-specialization/ 目录 1 - Gradient Descent 2 - Mini-Batch Gradient descent 3 - Momentum 4 - Adam 5 - Model with dif…

一步步编写操作系统 22 硬盘操作方法

硬盘中的指令很多&#xff0c;各指令的用法也不同。有的指令直接往command寄存器中写就行了&#xff0c;有的还要在feature寄存器中写入参数&#xff0c;最权威的方法还是要去参考ATA手册。由于本书中用到的都是简单的指令&#xff0c;所以对此抽象出一些公共的步骤仅供参考之用…

10.深度学习练习:Convolutional Neural Networks: Step by Step(强烈推荐)

本文节选自吴恩达老师《深度学习专项课程》编程作业&#xff0c;在此表示感谢。 课程链接&#xff1a;https://www.deeplearning.ai/deep-learning-specialization/ 目录 1 - Packages 2 - Outline of the Assignment 3 - Convolutional Neural Networks 3.1 - Zero-Paddin…

【HDU - 2639】Bone Collector II (第K大背包,dp,STLset)

题干&#xff1a; The title of this problem is familiar,isnt it?yeah,if you had took part in the "Rookie Cup" competition,you must have seem this title.If you havent seen it before,it doesnt matter,I will give you a link: Here is the link: http…

一步步编写操作系统 23 重写主引导记录mbr

本节我们在之前MBR的基础上&#xff0c;做个稍微大一点的改进&#xff0c;经过这个改进后&#xff0c;我们的MBR可以读取硬盘。听上去这可是个大“手术”呢&#xff0c;我们要将之前学过的知识都用上啦。其实没那么大啦&#xff0c;就是加了个读写磁盘的函数而已&#xff0c;哈…

11.深度学习练习:Keras tutorial - the Happy House(推荐)

本文节选自吴恩达老师《深度学习专项课程》编程作业&#xff0c;在此表示感谢。 课程链接&#xff1a;https://www.deeplearning.ai/deep-learning-specialization/ Welcome to the first assignment of week 2. In this assignment, you will: Learn to use Keras, a high-lev…

【HDU - 5014】Number Sequence(贪心构造)

题干&#xff1a; There is a special number sequence which has n1 integers. For each number in sequence, we have two rules: ● a i ∈ [0,n] ● a i ≠ a j( i ≠ j ) For sequence a and sequence b, the integrating degree t is defined as follows(“♁” deno…

一步步编写操作系统 24 编写内核加载器

这一节的内容并不长&#xff0c;因为在进入保护模式之前&#xff0c;我们能做的不多&#xff0c;loader是要经过实模式到保护模式的过渡&#xff0c;并最终在保护模式下加载内核。本节只实现一个简单的loader&#xff0c;本loader只在实模式下工作&#xff0c;等学习了保护模式…

12.深度学习练习:Residual Networks(注定成为经典)

本文节选自吴恩达老师《深度学习专项课程》编程作业&#xff0c;在此表示感谢。 课程链接&#xff1a;https://www.deeplearning.ai/deep-learning-specialization/ 目录 1 - The problem of very deep neural networks 2 - Building a Residual Network 2.1 - The identity…

【HDU - 5869】Different GCD Subarray Query(思维,数学,gcd,离线处理,查询区间不同数,树状数组 或 二分RMQ)

题干&#xff1a; This is a simple problem. The teacher gives Bob a list of problems about GCD (Greatest Common Divisor). After studying some of them, Bob thinks that GCD is so interesting. One day, he comes up with a new problem about GCD. Easy as it look…