排序算法排序的稳定性

Posted yadiel-cc

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了排序算法排序的稳定性相关的知识,希望对你有一定的参考价值。

排序的稳定性


2019-11-10  09:42:11  by冲冲

 

1、稳定性

① 定义:能保证两个相等的数,经过排序之后,其在序列的前后位置顺序不变。(A1=A2,排序前A1在A2前面,排序后A1还在A2前面)

② 意义:稳定性本质是维持具有相同属性的数据的插入顺序,如果后面需要使用该插入顺序排序,则稳定性排序可以避免这次排序。

比如,公司想根据“能力”和“资历”(以进入公司先后顺序为标准)作为本次提拔的参考,假设A和B能力相当,如果是稳定性排序,则第一次根据“能力”排序之后,就不需要第二次根据“”资历

排序了,因为“资历”排序就是员工插入员工表的顺序。如果是不稳定排序,则需要第二次排序,会增加系统开销。

 

2、分类

① 稳定性排序:冒泡排序,插入排序、归并排序、基数排序

② 不稳定性排序:选择排序、快速排序、希尔排序、堆排序

 

3、例析

(1)稳定性排序

① 冒泡排序

冒牌排序本质是,从左到右开始不断把大的元素往后调(或者,从右往左开始不断把小的元素往前调)。比较是比较相邻的两个元素,交换也是发生在这两个元素之间。所以,如果两个元素相等,你总不会无聊地把它俩交换一下吧。如果两个相等元素没有相邻,那么也会经过一波两两交换使他们相邻,此时也不会发生交换。

② 插入排序

插入排序本质是,在一个已经有序的小序列基础上,通过从右往左比较,一次插入一个元素。刚开始这个小序列只有一个元素。比较是从有序序列的末尾开始,想插入的元素和已经有序的最大者开始比较,如果比它大则直接插在其后面,否则一直往前比较,直到找到比它小的或与它相等的,然后插在其后面。

③ 归并排序

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

④ 基数排序

基数排序本质是,按照低位先排序,然后收集,再按照高位排序,然后再收集,依次类推,直到最高位。比如序列“171(1),331,171(2)”,低位排序(个位)结果是“171(1),331,171(2)”,高位排序(十位)结果是“331171(1),171(2)”,高位排序(百位)结果是“171(1),171(2),331”。

(2)不稳定性排序

① 选择排序

选择排序本质是,给每个位置选择剩下元素中最小的。比如给第一个位置选择最小的,给第二个位置选择剩余元素里面第二小的,依次类推。例如序列“5(1),8,5(2),2,9”,5(1)会和2交换,破坏稳定性。

② 快速排序

快速排序本质是,选取第一个元素为中枢元素a[center_index](index=0)。从两个方向入手,首先左边的i下标一直往右走,当a[i] > a[center_index]停止,由右边的j下标开始往左走,当a[j] <= a[center_index]停止,由左边i下标开始刚才的表演,重复上面的过程,直到i>j,交换a[j]和a[center_index],完成一趟快速排序。在中枢元素和a[j]交换的时候,很有可能把前面的元素的稳定性打乱,比如序列为 “5,3(1),4,3(2),8,11,9”, 现在中枢元素5和3(2)交换就会把元素3的稳定性打乱。不稳定发生在中枢元素和a[j]交换的时刻

③ 希尔排序

希尔排序本质是,按照不同步长对元素进行插入排序,当刚开始元素很无序的时候,步长最大,所以插入排序的元素个数很少,速度很快;当元素基本有序了,步长很小,插入排序对于有序的序列效率很高。所以,希尔排序的时间复杂度会比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个相同的元素之间的稳定性就被破坏了。所以,堆排序不是稳定的排序算法。

 

4、时间复杂度和空间复杂度

排序算法
类别 排序方法 时间复杂度 空间复杂度 稳定性 应用依据 剖析 
平均情况 最好情况 最坏情况 辅助内存
插入排序 直接插入 O(n2) O(n) O(n2)  O(1)  稳定 大部分已经排序  
希尔排序  O(n1.3) O(n)  O(n2  O(1)  不稳定    
选择排序 直接选择 O(n2) O(n2) O(n2)  O(1)  不稳定 n比较小  
堆排序 O(nlog2n)  O(nlog2n) O(nlog2n)   O(1)  不稳定 n比较大  
交换排序 冒泡排序 O(n2)  O(n)   O(n2 O(1)   稳定 n比较小  
快速排序 O(nlog2n)  O(nlog2n)  O(n2  O(log2n)~O(n)  不稳定 n比较大  
归并排序  O(nlog2n)  O(nlog2n) O(nlog2n)   O(1)  稳定 n比较大  
基数排序        O(1)  稳定    

 

 

 

 

 

 

 

 

 

 

 

 

 

以上是关于排序算法排序的稳定性的主要内容,如果未能解决你的问题,请参考以下文章

算法稳定性

数据结构之八大排序算法(C语言实现)

选择排序快速排序插入排序等经典八大算法稳定性分析

:排序算法 -- 排序算法介绍和分类算法的时间效率(时间频度和时间复杂度)算法的稳定性

几种排序算法的稳定性归纳

排序算法概述