前面有讲到了9种排序算法:

1.简单选择排序 2.堆排序        (1和2是属于选择排序)

3.直接插入排序 4.希尔排序     (3和4属于插入排序,有时把改进后的直接插入排序叫做二分插入)

5.冒泡排序         6.快速排序     (5和6属于交换排序.交换排序顾名思义是不停的交换数据位置.但实际上选择排序也在不停的交换元素,但次数较少,只有找到最大值才一次交换.侧重点还是在通过遍历或堆来选择出最值.而冒泡排序就是通过不停交换相邻元素得出最大值,快速排序也在不停交换元素使序列一步步接近有序.侧重在交换)

7.基数排序       8.桶排序         (7和8属于分配排序)

9.归并排序

面对这以多排序算法你可能郁闷着要自己排序时用哪种算法好呢? 每种算法适用哪些场景?

为了对比上面各种不同算法,可以从如下几个方面来考虑.

1.排序算法的稳定性

2.排序算法时间复杂度

3.排序算法空间复杂度

4.各种算法适用的最佳场景.

排序算法稳定性

所谓稳定性是指待排序的序列中有两元素相等,排序之后它们的先后顺序不变.假如为A1,A2.它们的索引分别为1,2.则排序之后A1,A2的索引仍然是1和2.

稳定也可以理解为一切皆在掌握中,元素的位置处在你在控制中.而不稳定算法有时就有点碰运气,随机的成分.当两元素相等时它们的位置在排序后可能仍然相同.但也可能不同.是未可知的.

另外要注意的是:算法思想的本身是独立于编程语言的,所以你写代码去实现算法的时候很多细节可以做不同的处理.采用不稳定算法不管你具体实现时怎么写代码,最终相同元素位置总是不确定的(可能位置没变也可能变了).而稳定排序算法是你在具体实现时如果细节方面处理的好就会是稳定的,但有些细节没处理得到的结果仍然是不稳定的.

比如冒泡排序,直接插入排序,归并排序虽然是稳定排序算法,但如果你实现时细节没处理好得出的结果也是不稳定的.

稳定性的用处

我们平时自己在使用排序算法时用的测试数据就是简单的一些数值本身.没有任何关联信息.这在实际应用中一般没太多用处.实际应该中肯定是排序的数值关联到了其他信息,比如数据库中一个表的主键排序,主键是有关联到其他信息.另外比如对英语字母排序,英语字母的数值关联到了字母这个有意义的信息.

可能大部分时候我们不用考虑算法的稳定性.两个元素相等位置是前是后不重要.但有些时候稳定性确实有用处.它体现了程序的健壮性.比如你网站上针对最热门的文章或啥音乐电影之类的进行排名.由于这里排名不会像我们成绩排名会有并列第几名之说.所以出现了元素相等时也会有先后之分.如果添加进新的元素之后又要重新排名了.之前并列名次的最好是依然保持先后顺序才比较好.

哪些算法是稳定的呢

稳定性算法:   基数排序 , 直接插入排序 , 冒泡排序, 归并排序

不稳定性算法: 桶排序,    二分插入排序,希尔排序, 快速排序,   简单选择排序,堆排序

各种算法稳定性详解

(1)基数排序(稳定)与桶排序(不稳定)

这两种算法都是属于分配排序算法.(利用元素值本身的信息直接映射到一个辅助序列中变成有序的.而不是通过与其他元素比较确定顺序位置)

基数排序因为在是把低位按顺序映射到一个临时序列中去,是依次序映射,没有涉及到数据位置的变动.然后再按高位顺序映射.所以相同元素也是按次序映射过去.所以是稳定的

如果数据元素没有重复的则采用简单桶排序,此时没有重复元素,所以自然不存在稳不稳定这一说.如果有重复元素得用改进的桶排序.此时辅助的临时数组只是通过索引来识别待排序元素的键值.丢失了其他信息(这是所有采用辅助的临时序列的算法中唯一一个会丢失信息的算法).假如待排序元素是一个map类型,按它的键值来排序.其他算法采用辅助序列时是把map类型做为元素去考虑的.而只有改进的桶排序不会把map类型当元素,只是利用到了键值信息. 这样一来就无法区分键值相同的信息,因此自然是不稳定的算法了啊.

(2)归并排序(稳定)

归并排序使得了递归的思想,把序列递归的分割成小序列,然后合并排好序的子序列.当有序列的左右两子序列合并的时候一般是先遍历左序列,所在左右序列如果有相等元素,则处在左边的仍然在前,这就稳定了.但是如果你非得先遍历右边序列则算法变成不稳定的了.虽然这样排出来的序也是对的,但变成了不稳定的,所以是不太好的实现.

(3)简单选择排序(不稳定)与堆排序(不稳定)

这两种算法都属于选择排序.(从待排序的元素中挑选出最大或最小值.下面的例子以最小值为例)

简单选择排序由于选出最小值后需要交换位置,位置一变就会变得不稳定.例如8  3  8  1.当从左往右遍历找最小值时,找到了1,这就需要把8跟1交换.这样两个相等元素8的位置就变了.

堆排序的话,也会存在跟上面一样的交换最大值的位置会导致不稳定.例如有大堆 8 8 6 5 2.先选出第一个最大值8,放最末尾.此时就不稳定了.因为第二个8就跑它前面去了.

(4)冒泡排序(稳定)与快速排序(不稳定)

这两种算法都属于交换排序.

冒泡是通过不停的遍历,以升序为例,如果相邻元素中左边的大于右边的则交换.碰到相等的时就不交换保持原位.所以是稳定的.当然如果你非得吃饱了撑着了,在碰到相等的时也交换下,那肯定变成不稳定的算法了.

快速排序是不稳定的.举例8   5   6  6 .以8为基准,第一趟交换后最后一个6跑到第一位,8到最后.第二趟交换.这个6跑到5的位置.变成有序的了.两个6位置变了,所以是不稳定的.

(5)直接插入(稳定),二分插入排序(不稳定)与希尔排序(不稳定)

直接插入时是先在已排序好的的子序列中找到合适的位置再插入.假设左边是已排序的,右边是没排序的.通过从后向前遍历已排序序列,然后插入,此时相等元素依然可以保持原有位置.但是如果你从前向后遍历已排序序列就会是不稳定排序了.

二分插入排序是不稳定的,因为通过二分查找时得到的位置不稳定.例如3 4 4 5 4.但把最后一个4插入时肯定会跑到第二个4前面去了.所以是不稳定的.

通过上面的分析我们可以得出这样一个经验之谈.

1.只要不涉及到两个元素之间位置的交换就肯定是稳定的排序算法.比如归并排序,基数排序.(桶排序不稳定是个特例,因为它丢失了附带信息,不然的话可以弄成稳定排序的)

2.在涉及到不同位置元素交换的算法中除了冒泡和直接插入排序是稳定的,其他都是不稳定的.

你可以这样想,之所以出现相同元素位置变了就是其中一个交换位置时从另一个头顶跳过去了,而冒泡算法是相邻位置互换,跳不过去的,碰到相等元素的时候就停住不交换了.

而直接插入排序是往已排好序的序列中插入.所以你通过由后往前遍历碰到相等的时就停住,这样也能保持稳定.但记住一定得从后往前遍历,不然也会不稳定.(所以说直接插入是半稳吧,而冒泡是非常的稳啊,除非你闲得蛋痛非得把两相等的元素两两交换)

各种排序算法比较(1):稳定性相关推荐

  1. 在遗传算法中出现等式约束_排序算法中的稳定性-等式的处理

    在遗传算法中出现等式约束 by Onel Harrison 通过Onel Harrison 排序算法中的稳定性-等式的处理 (Stability in Sorting Algorithms - A T ...

  2. 如果我问你:排序算法的「稳定性」有何意义?你怎么回答?

    点击上方"朱小厮的博客",选择"设为星标" 后台回复"加群"加入公众号专属技术群 欢迎跳转到本文的原文链接:https://honeypps ...

  3. 排序算法为什么要求稳定性

    堆排序.快速排序.希尔排序.直接选择排序是不稳定的排序算法,而基数排序.冒泡排序.直接插入排序.折半插入排序.归并排序是稳定的排序算法. 首先,排序算法的稳定性大家应该都知道,通俗地讲就是能保证排序前 ...

  4. 软考排序算法时间复杂度和稳定性助记

    B站马士兵老师的视频--30秒让你记住所有排序算法-宋词记忆法

  5. Java排序算法——冒泡排序 及其稳定性和时间复杂度

    冒泡排序(Bubble Sort) 它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序错误就把他们交换过来.走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成 ...

  6. 排序算法时间复杂度和稳定性

    速查表

  7. 漫画 | 程序媛小姐姐带你一次了解什么是排序算法

    来源 | 小齐本齐 封图 | CSDN 付费下载自视觉中国 插入排序 借用<算法导论>里的例子,就是我们打牌的时候,每新拿一张牌都会把它按顺序插入,这,其实就是插入排序. 齐姐声明:虽然我 ...

  8. 面试前你必须知道的三个排序算法

    今天分享的是三种排序算法,在面试.实际编程中经常会碰到和使用到的,我会带领大家从分析排序算法技巧上以及代码实现上全面理解这一知识点的掌握. 一.如何分析一个「排序算法」 1. 执行效率 ① 最好.最坏 ...

  9. 《排序算法系列一、简单选择排序》

    2019独角兽企业重金招聘Python工程师标准>>> 一.简单选择排序 描述:给定待排序序列A[ 0......n ] ,选择出第i小元素,并和A[i]交换,这就是一趟简单选择排序 ...

最新文章

  1. 重磅推荐:保姆级Java技术图谱!够学到元宵节了,赶紧收藏!
  2. c code first mysql_Code First for MySql命令操作
  3. oracle数据库查表_Oracle面试问题-技术篇
  4. mac安装虚拟机centos7_虚拟机------安装centos7 系统(四)
  5. CSS Margin(外边距)
  6. ionic3使用第三方图标
  7. 2012、12、17
  8. 学生选课系统简单说明
  9. 蓝牙音乐之AVRCP常用指令介绍
  10. 怎么把外部参照合并到图纸_为什么CAD图纸作为外部参照插入时位置变了?
  11. php自我介绍50字,简短自我介绍50字
  12. GameCenter接入
  13. New Year Snowmen codeforces 140C
  14. rk3566 HDMI 热插拔HDMI显示无信号
  15. 微软输入法设置小鹤双拼
  16. 拯救流浪猫 | 「喵先锋」系列数字版权盲盒明日开抢
  17. 高版本Chrome网页直接播放海康威视大华RTSP流方案,不需服务器转码转流,支持H.265、H.264及2K/4K高清视频
  18. 精通 Grails: 用 JSON 和 Ajax 实现异步 Grails
  19. word中使页眉不同的同时,页码相同 的问题解决
  20. Mysql 数据库执行计划 EXPLAIN SELECT * FROM

热门文章

  1. Mac——技巧:笔记本如何关闭fn功能
  2. Weex 300行代码开发一款简易的跑步App
  3. 服务器虚拟化vmware价格,vmware服务器虚拟化实施方案(vmware服务器虚拟化收费)...
  4. 机器学习和深度学习路线
  5. 徕卡LGO软件(Leica Geo Office) v8.4 官方中文版
  6. 西门子大型程序fanuc机器人焊装 包括1台 西门子1500PLC程序,2台触摸屏TP1500程序
  7. 排列组合简介以及相关问题
  8. 英雄无敌3 死亡阴影 修改器
  9. 小程序this.setData
  10. Java charAt() 方法