分析一下常见的排序算法的稳定性,每个都给出简单的理由。

  • 冒泡排序

    冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,我想你是不会再无聊地把他们俩交换一下的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。

  • 选择排序

    选择排序是给每个位置选择当前元素最小的,比如给第一个位置选择最小的,在剩余元素里面给第二个元素选择第二小的,依次类推,直到第n - 1个元素,第n个元素不用选择了,因为只剩下它一个最大的元素了。那么,在一趟选择,如果当前元素比一个元素小,而该小的元素又出现在一个和当前元素相等的元素后面,那么交换后稳定性就被破坏了。比较拗口,举个例子,序列5 8 5 2 9,我们知道第一遍选择第1个元素5会和2交换,那么原序列中2个5的相对前后顺序就被破坏了,所以选择排序不是一个稳定的排序算法。

  • 插入排序

    插入排序是在一个已经有序的小序列的基础上,一次插入一个元素。当然,刚开始这个有序的小序列只有1个元素,就是第一个元素。比较是从有序序列的末尾开始,也就是想要插入的元素和已经有序的最大者开始比起,如果比它大则直接插入在其后面,否则一直往前找直到找到它该插入的位置。如果碰见一个和插入元素相等的,那么插入元素把想插入的元素放在相等元素的后面。所以,相等元素的前后顺序没有改变,从原无序序列出去的顺序就是排好序后的顺序,所以插入排序是稳定的。

  • 快速排序

    快速排序有两个方向,左边的i下标一直往右走,当a[i] <= a[center_index],其中center_index是中枢元素的数组下标,一般取为数组第0个元素。而右边的j下标一直往左走,当a[j] > a[center_index]。如果i和j都走不动了,i <= j,交换a[i]和a[j],重复上面的过程,直到i > j。 交换a[j]和a[center_index],完成一趟快速排序。在中枢元素和a[j]交换的时候,很有可能把前面的元素的稳定性打乱,比如序列为5 3 3 4 3 8 9 10 11,现在中枢元素5和3(第5个元素,下标从1开始计)交换就会把元素3的稳定性打乱,所以快速排序是一个不稳定的排序算法,不稳定发生在中枢元素和a[j] 交换的时刻。

  • 归并排序

    归并排序是把序列递归地分成短序列,递归出口是短序列只有1个元素(认为直接有序)或者2个序列(1次比较和交换),然后把各个有序的段序列合并成一个有序的长序列,不断合并直到原序列全部排好序。可以发现,在1个或2个元素时,1个元素不会交换,2个元素如果大小相等也没有人故意交换,这不会破坏稳定性。那么,在短的有序序列合并的过程中,稳定是是否受到破坏?没有,合并过程中我们可以保证如果两个当前元素相等时,我们把处在前面的序列的元素保存在结果序列的前面,这样就保证了稳定性。所以,归并排序也是稳定的排序算法。

  • 基数排序

    基数排序是按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高位。有时候有些属性是有优先级顺序的,先按低优先级排序,再按高优先级排序,最后的次序就是高优先级高的在前,高优先级相同的低优先级高的在前。基数排序基于分别排序,分别收集,所以其是稳定的排序算法。

  • 希尔排序(shell)

    希尔排序是按照不同步长对元素进行插入排序,当刚开始元素很无序的时候,步长最大,所以插入排序的元素个数很少,速度很快;当元素基本有序了,步长很小, 插入排序对于有序的序列效率很高。所以,希尔排序的时间复杂度会比O(n^2)好一些。由于多次插入排序,我们知道一次插入排序是稳定的,不会改变相同元素的相对顺序,但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱,所以shell排序是不稳定的。

  • 堆排序

    我们知道堆的结构是节点i的孩子为2 * i和2 * i + 1节点,大顶堆要求父节点大于等于其2个子节点,小顶堆要求父节点小于等于其2个子节点。在一个长为n 的序列,堆排序的过程是从第n / 2开始和其子节点共3个值选择最大(大顶堆)或者最小(小顶堆),这3个元素之间的选择当然不会破坏稳定性。但当为n / 2 - 1, n / 2 - 2, ... 1这些个父节点选择元素时,就会破坏稳定性。有可能第n / 2个父节点交换把后面一个元素交换过去了,而第n / 2 - 1个父节点把后面一个相同的元素没 有交换,那么这2个相同的元素之间的稳定性就被破坏了。所以,堆排序不是稳定的排序算法。

  • 综上,得出结论: 
  • 稳定算法:冒泡排序、插入排序、归并排序、基数排序
  • 不稳定算法 :选择排序、快速排序、希尔排序、堆排序
  • 稳定性的意义

    • 如果只是简单的进行数字的排序,那么稳定性将毫无意义。
    • 如果排序的内容仅仅是一个复杂对象的某一个数字属性,那么稳定性依旧将毫无意义
    • 如果要排序的内容是一个复杂对象的多个数字属性,但是其原本的初始顺序毫无意义,那么稳定性依旧将毫无意义。
    • 除非要排序的内容是一个复杂对象的多个数字属性,且其原本的初始顺序存在意义,那么我们需要在二次排序的基础上保持原有排序的意义,才需要使用到稳定性的算法,例如要排序的内容是一组原本按照价格高低排序的对象,如今需要按照销量高低排序,使用稳定性算法,可以使得想同销量的对象依旧保持着价格高低的排序展现,只有销量不同的才会重新排序。(当然,如果需求不需要保持初始的排序意义,那么使用稳定性算法依旧将毫无意义)。

转载自:https://www.cnblogs.com/tigerson/p/7156648.html

常见的排序算法的稳定性相关推荐

  1. 什么是排序算法的稳定性?

    什么是排序算法的稳定性? 今天来了解一下排序算法的稳定性的定义和一些常见排序算法的稳定性,一起来看看吧! 我们知道排序算法有时间.空间复杂度,那稳定性是什么意思呢?和它们有关吗? 文章目录 什么是排序 ...

  2. 八大排序算法的稳定性及时间复杂度

    前言: 首先清楚何谓稳定性? 通俗地讲就是能保证排序前2个相等的数其在序列的前后位置顺序和排序后它们两个的前后位置顺序相同.在简单形式化一下,如果Ai = Aj,Ai原来在Aj位置前,排序后Ai还是要 ...

  3. 什么是排序算法的稳定性

    排序算法的稳定性,通俗地讲就是能保证排序前2个相等的数其在序列的前后位置顺序和排序后它们两个的前后位置顺序相同. 在简单形式化一下,如果Ai = Aj, Ai原来在位置前,排序后Ai还是要在Aj位置前 ...

  4. 数据结构几种常见的排序算法

    学习过经典的冒泡排序算法后,我们将继续深入学习,了解更多算法排序 插入排序 直接插入排序 直接插入排序其基本思想是:把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,指导所有记录插 ...

  5. 七种常见的排序算法总结

    目录 引言 1.什么是排序? 2.排序算法的目的是什么? 3.常见的排序算法有哪些? 一,插入排序 1.基本思想 2.代码实现 3.性能分析 4.测试 二,希尔排序(缩小增量排序) 1.基本思想 2. ...

  6. 基于比较的常见的排序算法

    目录 写在前面 排序 稳定性 排序的分类 常见的基于比较的排序 直接插入排序 代码 性能分析 总结 代码优化 折半插入 希尔排序 希尔排序 如何分组 代码 性能分析 选择排序 代码 性能分析 双向选择 ...

  7. 排序算法的稳定性 (什么样的排序是不稳定的)

    有两个6,a[0]和a[3].排序结果就有两种可能: 如果排序结束后,a[0]可以保证一定在a[3]前头,也就是他们原有的顺序不变,那这种排序算法就是稳定的.(比如常见的冒泡排序.基数排序.插入排序. ...

  8. 排序算法的稳定性及其意义

    稳定性的定义 假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,ri=rj,且ri在rj之前,而在排序后的序列中,ri仍在rj之前,则称这 ...

  9. 内部排序算法的稳定性

    1.排序 排序是计算机程序设计中的一个重要操作,因此学习和研究各种排序算法是一个重要的课题. 2.排序种类 根据排序记录的数量和排序过程中的存储器不同,可以将排序分为内部排序和外部排序. 内部排序:指 ...

最新文章

  1. Remove Duplicates from Sorted List 去除链表中重复值节点
  2. mysql php7安装配置_centos7无网络下安装部署php7.1.33+mysql5.7.28+apache2.4.6-Go语言中文社区...
  3. 机器学习Tensorflow基础知识、张量与变量
  4. x5内核有什么优点_接上U盘就是NAS私有云,蒲公英X5入手测评
  5. LeetCode 37 解数独
  6. python 文件指针及文件覆盖
  7. vue aplayer 进度条无法拖动_「最近项目小结」使用Vue实现一个简单的鼠标拖拽滚动效果插件...
  8. 【转】Fresco之强大之余的痛楚
  9. matlab求两向量夹角_高等数学之向量代数与空间解析几何知识点与题型总结
  10. linux自动实现项目跑,利用Linux中的crontab实现分布式项目定时任务功能
  11. 最新基于高德地图的android进阶开发(5)地图的基本操作、事件监听、用户UI、图层选择等
  12. Android实现汤姆猫小游戏
  13. DNF自动获取C语言,VC++开发硬件DNF搬砖项目全新发车,想上车的要赶紧
  14. 基于计算机视觉原理的自主足球机器人位置规划,基于计算机视觉原理的自主足球机器人位置规划...
  15. 小于n的最大素数python_求m下n个最大素数
  16. Facebook的原罪与区块链的救赎
  17. clang-format代码格式化风格选项详细说明
  18. 聚类分析在用户行为中的实例_聚类分析案例
  19. AWS云上基础服务体验课程
  20. RT-Thread物联网操作系统介绍:10、计数信号量

热门文章

  1. #午安,努力#11.30
  2. 一个红包系统的设计与实现(1)-提出问题
  3. Exercise 1.30/1.31/1.32/1.33
  4. css设置个性字体大小,css设置字体大小的属性名是什么
  5. 指针(指向的是头发)
  6. 浅谈如何写好一个接口
  7. pythonic风格_如何写出Pythonic风格的代码
  8. freemarker html转义字符,freemarker防止json转义
  9. 假如你能给「微信」增加一个小功能
  10. Linux下使用 ipset 封大量IP及ipset参数说明