排序方式 时间复杂度(最好/最坏情况) 空间复杂度 稳定性
冒泡排序 O(n^2)/O(n) O(1) 稳定
选择排序 O(n^2) O(1) 不稳定
直接插入排序 O(n^2)/O(n) O(1) 稳定
希尔排序 O(n^1.3) O(1) 不稳定
堆排序 O(nlog_2 n) O(1) 不稳定
归并排序 O(nlog_2 n) O(n) 稳定
基数排序 O(d(n+rd))/O(d(r+n)) O(rd+n) 稳定
快速排序 O(nlog_2 n)/ O(n^2) O(log_2 n) 不稳定
算法本质及稳定性分析:
(1)冒泡排序:稳定,如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个元素相邻起来,
最终也不会交换它俩的位置,相同元素经过排序后顺序并没有改变。所以冒泡排序是一种稳定排序算法。
(2)选择排序:不稳定,选择排序即是给每个位置选择待排序元素中当前最小的元素。
比如给第一个位置选择最小的,在剩余元素里面给第二个位置选择次小的,依次类推,直到第n-1个元素,
第n个元素不用选择了,因为只剩下它一个最大的元素了。举个例子:序列5 8 5 2 9, 第一趟选择第1个元素5会与2进行交换,
那么原序列中两个5的相对先后顺序也就被破坏了。所以选择排序不稳定。
(3)插入排序:稳定,插入排序是在一个已经有序的小序列的基础上,一次插入一个元素。
如果遇见一个与插入元素相等的,那么把待插入的元素放在相等元素的后面。相等元素的前后顺序没有改变,
从原无序序列出去的顺序仍是排好序后的顺序,所以插入排序是稳定的。
(4)希尔排序:不稳定,希尔排序是按照不同步长对元素进行插入排序,一次插入排序是稳定的,不会改变相同元素的相对顺序,
但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,稳定性就会被破坏,
所以希尔排序不稳定。
(5)堆排序:不稳定,堆排序的过程是从第n/2开始和其子节点共3个值选择最大(大顶堆)或者最小(小顶堆),
这3个元素之间的选择当然不会破坏稳定性。但当为n/2-1, n/2-2, ...这些父节点选择元素时,
有可能第n/2个父节点交换把后面一个元素交换过去了,而第n/2-1个父节点把后面一个相同的元素没有交换,
所以堆排序并不稳定。
(6)归并排序:稳定 ,指的是将两个已经排序的序列合并成一个序列的操作。归并排序算法依赖归并操作。
在分解的子列中,有1个或2个元素时,1个元素不会交换,2个元素如果大小相等也不会交换。
在序列合并的过程中,如果两个当前元素相等时,我们把处在前面的序列的元素保存在结果序列的前面,
所以,归并排序也是稳定的。
(7)基数排序(桶子排序): 时间复杂度为:posCount * (length + length) ;其中 posCount 为数组中最大元素的最高位数;
简化下得:O( k*n ) ;其中k为常数,n为元素个数;该算法的空间复杂度就是在分配元素时,使用的桶空间;
所以空间复杂度为:O(10 × length)= O (length);
稳定,是按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高位。
基数排序基于分别排序,分别收集,所以是稳定的。
(8)快速排序:不稳定,在中枢元素和序列中一个元素交换的时候,很有可能把前面的元素的稳定性打乱。
还是看一个小实例:6 4 4 5 4 7 8 9,第一趟排序,中枢元素6和第三个4交换就会把元素4的原序列破坏,
所以快速排序不稳定。