排序的稳定性

什么是排序稳定性?  

  通俗地讲就是在排序前A的位置是 i ,B的位置是 j,此时 i < j,则如果在排序后A的位置还是在B之前,那么称它是稳定的。

它的好处是,如果排序算法是稳定的,那么第一个排序结果可以为另一个排序所用。比如基数排序,先按低位排序,逐次按高位排序,低位相同的元素其顺序在高位也相同时是不会改变的。

首先给出一张在前一个博客“时间复杂度入门理解”中出现过的一副图,给出相关排序的稳定性:

  

接下来,将解释图中某些排序是不稳定的的原因。

I)为什么希尔排序不稳定?

A:首先要知道 Shell 排序是基于插入排序的优化排序,插入排序每次本身只能插入一位数据,希尔排序按照步长对多个元素进行插入排序。我们知道一次插入排序是稳定的,但是同时对多组数据进行插入排序,很明显就稳定了,举例:

有这样一组数:[ 13 14 94 33 82 25 59 94 65 23 45 27 73 25 39 10 ]

以第一轮是步长为5的希尔排序为例:

Before Shell Sort:

After Shell Sort:

很明显,之前 94 相对于 33 的位置就变了,这就是同时进行多次插入排序所导致的不稳定性。

II)为什么快速排序不稳定?

A:快排的思想是先设一个中枢元素(也称是基准数,对照用),对两遍进行排列,需要满足左边的元素都比中枢元素小,右边元素都比中枢元素大,随后对左和右的子序列也进行这样的操作(分治)。而该排序不稳定的关键就是中枢元素在调换到序列中间的时候,会破坏了原来位于中央的元素的稳定性,比如有一个序列:

6 1 2 7 9 3 4 5 10 8 ,我们定义 6 为中枢元素

进行第一轮快排后,得3 1 2 5 4 6 9 7 10 8

这样操作就会把 3 的稳定性破坏。所以快排是一个不稳定的排序算法,不稳定发生在中枢元素的交换时刻。

III)为什么选择排序是不稳定的?

A:选择排序的操作是这样:先在未排序的序列中选择最小的元素(或最大的元素),把它放入第一个位置,再在剩余未排序序列中选择第二小的,放在第二个位置...以此类推,直到所有序列排序完毕。但是,这样直接让最小元素与第一个位置上的元素进行交换,会破坏第一个元素的稳定性。

举个例子:6 2 1 7 9 3 4 5 10 8

在6 和 1 的交换同时,6 与 2的稳定性就被破坏了。

IV)为什么堆排序是不稳定的?

A:堆的结构是第 i 个结点的左子结点为 2i ,右子结点为2i + 1,子结点 i 的父结点的位置在 floor( (i-1)/2 ),最大堆要求父结点要大于它的两个子结点,最小堆要求父结点要小于它的两个子结点。而堆排序就是移除位于第一个数据的根结点,并做做大堆调整的递归运算。

在一个长为n的序列中,首先从第 n/2 个结点和其子结点一共三个结点开始选择是最大堆还是最小堆,这三个元素的选择当然并不会影响稳定性。但是之后第n/2 -1 ,n/2 -2, ... 2, 1 个结点开始选择就会影响稳定性了。因为有可能第 n/2 -2 个父结点把其后的一个元素交换了,而第 n/2 -3 个父结点的后一个结点却没有被交换,那么它们之间的稳定性就被破坏了。

注意

  排序算法是否为稳定的是由具体算法决定的,不稳定的算法在某种条件下可以变为稳定的算法,而稳定的算法在某种条件下也可以变为不稳定的算法。比如冒泡,若让交换的条件改成 r[j] >= r[j+1],两个相等的记录就会交换位置,从而变成不稳定的算法。

时间: 2024-10-10 15:45:57

排序的稳定性的相关文章

算法学习 - 选择排序的稳定性讨论(C++实现)

选择排序 选择排序的思想很简单. ?每次选择当前的最小数字. ?向后移动一位,选择第二小的数字. ?- ?移动到倒数第二位,操作后截止. 还不懂的附上百度百科选择排序. 稳定性 所以到底是不是稳定的呢? 不稳定解释 看过上面百度百科链接的人就会觉得一定不是稳定的啊. 因为例如如下: [5 8 5 2 9 4] 这个在第一次选择最小的时候,就把5和2的位置掉换了,变成如下: [2 8 5 5 9 4] ========= [5 8 5 2 9 4]//这是原始数组,观察数字5的位置. 第一次操作就

算法导论学习之线性时间排序+排序算法稳定性终结

前面我们学习的几种排序算法都是基于比较的,对于任何输入数据他们都是适用的,其最坏的时间复杂度不会低于nlgn: 但对于一些比较特殊的输入数据,我们可以不采取比较的方法而是采用其它的方法对其进行排序,以达到线性的时间复杂度.下面就来介绍三种这样的算法:计数排序,基数排序,桶排序(因为这几种算法不常见,我只实现了计数排序,其它两种排序用伪代码表示). 一.计数排序 算法思想:给定n个位于0–k之间的数(k是一个不太大的整数),我们可以统计出每个数前面有多少个小于它的数,然后就可以直接确定这个数在数组

排序算法稳定性

Contents 定义 排序前后两个相等的数相对位置不变,则稳定 稳定性的好处 从一个键上排序,然后再从另一个键上排序,第一个键排序的结果可以为第二个键排序所用 各排序算法的稳定性 堆排序.快速排序.希尔排序.直接选择排序不是稳定的排序算法 基数排序.冒泡排序.直接插入排序.折半插入排序.归并排序是稳定的排序算法 冒泡排序 小的元素往前调或者把大的元素往后调 比较是相邻的两个元素比较,交换也发生在这两个元素之间 稳定排序算法 选择排序 每个位置选择当前元素最小的 在一趟选择中,如果当前元素比一个

各种排序的稳定性,时间复杂度、空间复杂度、稳定性

各种排序的稳定性,时间复杂度.空间复杂度.稳定性总结如下图: 关于时间复杂度: (1)平方阶(O(n2))排序 各类简单排序:直接插入.直接选择和冒泡排序: (2)线性对数阶(O(nlog2n))排序 快速排序.堆排序和归并排序: (3)O(n1+§))排序,§是介于0和1之间的常数. 希尔排序 (4)线性阶(O(n))排序 基数排序,此外还有桶.箱排序. 关于稳定性: 稳定的排序算法:冒泡排序.插入排序.归并排序和基数排序 不是稳定的排序算法:选择排序.快速排序.希尔排序.堆排序 #inclu

【排序算法】(1)排序的稳定性

排序的稳定性 2019-11-10  09:42:11  by冲冲 1.稳定性 ① 定义:能保证两个相等的数,经过排序之后,其在序列的前后位置顺序不变.(A1=A2,排序前A1在A2前面,排序后A1还在A2前面) ② 意义:稳定性本质是维持具有相同属性的数据的插入顺序,如果后面需要使用该插入顺序排序,则稳定性排序可以避免这次排序. 比如,公司想根据“能力”和“资历”(以进入公司先后顺序为标准)作为本次提拔的参考,假设A和B能力相当,如果是稳定性排序,则第一次根据“能力”排序之后,就不需要第二次根

排序的稳定性(概念明晰)

当待排序记录的关键字均不相同时,排序结果是唯一的,否则排序结果不唯一. 在待排序的文件中,若存在多个关键字相同的记录,经过排序过后这些具有相同关键字的记录之间的相对次序保持不变 该排序方法是稳定的:若具有相同关键字之间的相对次序发生变化,则称这种排序方法不稳定. 注意:排序算法的稳定性是针对所有输入实例而言的.即在所有可能的输入实例中,只要有一个实例使得算法不满足稳定性要求,则该排序算法就是不稳定的.

数据结构——排序——8种常用排序算法稳定性分析

首先,排序算法的稳定性大家应该都知道,通俗地讲就是能保证排序前2个相等的数其在序列的前后位置顺序和排序后它们两个的前后位置顺序相同.在简单形式化一下,如果Ai = Aj, Ai原来在位置前,排序后Ai还是要在Aj位置前. 其次,说一下稳定性的好处.排序算法如果是稳定的,那么从一个键上排序,然后再从另一个键上排序,第一个键排序的结果可以为第二个键排序所用.基数排序就是这样,先按低位排序,逐次按高位排序,低位相同的元素其顺序再高位也相同时是不会改变的.另外,如果排序算法稳定,对基于比较的排序算法而言

常用排序算法 - 稳定性和复杂度分析

一.前言 上一篇,只是简单的记录了常用算法的主要思想以及代码实现( 常用算法记录 ); 这次简单的记录一下算法的稳定性以及复杂度 二.稳定性 1. 稳定性的定义 如果两个相等的数据的先后位置,排序前后保持不变的话,那就是稳定的,反之,就是不稳定: 例如:A[i] == A[j] , A[i]的位置在A[j]之前,排序后,A[i]的位置依然在A[j]之前: 2. 稳定性的好处 (1)如果排序算法是稳定的,那么从一个键上排序,然后再从另一个键上排序,第一个键排序的结果可以为第二个键排序所利用. 基数

转:各种排序算法的稳定性和时间复杂度小结

选择排序.快速排序.希尔排序.堆排序不是稳定的排序算法, 冒泡排序.插入排序.归并排序和基数排序是稳定的排序算法. 冒泡法:  这是最原始,也是众所周知的最慢的算法了.他的名字的由来因为它的工作看来象是冒泡:  复杂度为O(n*n).当数据为正序,将不会有交换.复杂度为O(0). 直接插入排序:O(n*n) 选择排序:O(n*n) 快速排序:平均时间复杂度log2(n)*n,所有内部排序方法中最高好的,大多数情况下总是最好的. 归并排序:log2(n)*n 堆排序:log2(n)*n 希尔排序: