今天专门来讲一下排序算法的稳定性。
1.稳定性的含义
这个稳定性的意思就是说,在排序过程中,具有相同数值的对象的相对顺序被不被打乱。
如果可以保证不被打乱就是稳定的,如果不能保证就是不稳定的。
2.稳定性的作用
由稳定性的定义我们知道,只有对象的某个属性相同,才有稳定性的概念。
而稳定性的意义更多是因为,除了相同的属性,剩下的那些不同的属性。
试想,如果A和B两个对象,B是A的引用或者B是A的拷贝。那么A和B的值就是完全一样的,那么其实谁在前面,谁在后面没有什么差别。
就是因为如果两个对象的其余部分不同,谁在前面和谁在后面,在关注它们不同属性的问题的时候,它们的顺序也才有了意义。
3.具体算法的稳定性
稳定:插入排序、冒泡排序、归并排序、计数排序、基数排序、桶排序
不稳定:快速排序、堆排序、希尔排序、选择排序
这里主要就是说一下它们为什么是稳定的或者不稳定的。
(1)如果每次变换都只是交换相邻的两个元素,那么就是稳定的。
所以,冒泡排序、插入排序、归并排序是稳定的。
(2)如果每次都有某个元素和比较远的元素的交换操作,那么就是不稳定的。
比如,快排,在partition的最后要将hi元素和pivot元素交换
比如,堆排,每次排一个元素就要将堆顶元素和最后一个元素交换
比如,选择排序,每次选出当前最大值,就要和最后的元素交换
(3)其余的排序方法
①计数、基数、桶排
个人认为说计数排序是稳定的是没有意义的,因为当我们在计数排的时候,如果又要求了使用的额外空间是常量的话,
相当于就是将用来比较的元素属性等同于元素本身了,所以由上面我对稳定性意义的讨论,计数排序确实是稳定的,但是是没有意义的。
当然如果每次用一个拉链法这种方法来存储元素,还是有意义的稳定性,但是这样就不能以常数空间完成任务了。
而基数排序是基于计数排序实现的。
桶排序原理和计数排序一致。
它们都是稳定的。
②希尔排序
希尔排序是一种对于插入排序的改进。
但是由于它中间将所有元素分为了若干个不同的排序序列,如果两个比较属性相同的元素被分到了不同的序列,
很可能就会打乱相对顺序,所以希尔排序是不稳定的。
注意:
1.这里说的几种稳定排序算法都是说,实现的时候通过注意不将相同比较属性的元素交换位置实现稳定性。
但是如果某一个实现之中没有注意,很可能就会打乱稳定性。
2.不稳定也不是说一定会打乱相对顺序,只是说不对相对顺序提供任何保证。