各种排序总结

对网上一篇文章(网上好几篇相同的文章,不知道最原始的地址了)做了少许修改


以下排序均以非降序排序为例

(1)冒泡排序 bubble sort

     在每次比较过程中,如果当前元素比下一个元素大,才会将这两个元素进行交换,否则不交换,因此当俩元素相等时不会交换,也即相同元素不会交换位置,所以冒泡排序是稳定的。
复杂度: 平均O(N2), 最坏O(N2), 空间O(1)


(2)简单选择排序 simple selection sort

     在第i趟排序过程中,选择出第i小的元素,然后与数组i处元素进行交换,这样第i小的元素就放置到数组i处了。乍看一下以为选择排序是稳定的,其实不然,因为在交换过程中,会将其中相等的元素交换到后面,导致两个相等元素的相对位置发生改变,如5 2 5 1。所以选择排序是不稳定的
复杂度:平均O(N2), 最坏O(N2), 空间O(1)


(3)直接插入排序 insertion sort

     在第i趟排序过程中(前i-1趟排序已经产生了从0到i-1处的有序数组),i处元素与i-1处元素比较,如果a[i] < a[i-1],则将a[i - 1]放置到a[i];然后原a[i]会继续和a[i - 2] ... 进行比较,直到出现a[i - k] <= 原a[i]为止,则i - k + 1即为原a[i]应放入的位置。可见直接插入排序是稳定的。
复杂度:平均O(N2), 最坏O(N2), 空间O(1)


(4)快速排序 quick sort

     设数组的中枢元素下标为center_index,一般取0(为了得到更好的性能,优化时会取左端,中间,右端三个元素的中位数),快速排序有两个方向,左边的i下标一直往右走(当a[i] <= a[center_index]时);而右边的下标j一直往左走(a[center_index] < a[j]);如果i和j都走不动了,且i <= j,交换a[i]和a[j],然后重复上述过程,直到i > j。交换a[j]和a[center_index],完成一趟快速排序。在中枢元素和a[j]交换的时候,很有可能把前面的元素的稳定性打乱,比如序列为5 3 3 4 3 8 9 10 11,现在中枢元素5和a[4] = 3交换,就会把元素3的稳定性打乱,所以快速排序是一种不稳定的排序算法,不稳定发生在中枢元素和a[j]发生交换的时刻。
复杂度:平均O(NlogN), 最坏O(N2), 空间O(NlogN)


(5)归并排序 merge sort

     归并排序是把序列递归地分成短序列,递归出口是短序列只有一个元素(认为直接有序),然后把各个有序的短序列合并成一个有序的长序列,不断合并直到全部排好序。在短序列的合并过程中,左半部分的有序序列和右半部分的有序序列,每次比较两个元素时,都可以保证在元素相等时把左半部分的元素放在结果序列的前面,这样就保证了稳定性,所以归并排序是稳定的。
复杂度:平均O(NlogN), 最坏O(NlogN), 空间O(N)


(6)基数排序

     基数排序是按照低位先排序,然后收集;再逐步向高位进行排序,然后再收集。以此类推,直到最高位。有时候有些属性是有优先级顺序的,先按低优先级排序,再按高优先级排序,最后的次序就是高优先级高的在前,高优先级相同的低优先级高的在前。基数排序基于分别排序,分别收集,所以是一种稳定的排序算法
     设待排序列为n个记录,d个关键码,关键码的取值范围为radix,则进行链式基数排序的时间复杂度为O(d(n + radix)),其中,一趟分配时间复杂度为O(n),一趟收集时间复杂度为O(radix),共进行d趟分配和收集。空间效率:需要2*radix个指向队列的辅助空间,以及用于静态链表(用数组表示的链表)的n个指针。
复杂度:平均O(d(n + radix))   最坏O(d(n + radix))     空间O(radix)(没怎么看懂为什么空间复杂度是radix?)


(7)希尔排序 Shell sort

     希尔排序是按照不同步长对元素进行插入排序,步长从长到短,刚开始的时候,步长最长,所以插入排序的元素个数很少,速度很快;当元素基本有序了,步长很小,插入排序对于有序的序列效率很高。所以希尔排序的时间复杂度会比O(n^2)好一些。我们知道一次插入排序是稳定的,不会改变相同元素的相对顺序,但由于多次插入排序,在不同的插入排序过程中,相同元素可能在各自的插入排序中移动,最后其稳定性就会被打乱,所以希尔排序是不稳定的。
     举个例子,比如待排序数组已经排序到如下时,此时步长缩短为2
     1     4      3     3      5     7
     1A          1B           1C
            2A          2B          2C
     第一组使用直接插入排序,不需要移动元素,已经有序;第二组元素经过直接插入排序后变为3 4 7
     因此步长为2时希尔排序结果为1 3 3 4 5 7,其中两个3的相对位置已经被交换了。


(8)堆排序 Heap sort

     设堆中的元素个数为n,则节点i(0 <= i <= n/2)的孩子节点为2*i和2*i + 1,小顶堆要求父节点大于等于其两个孩子节点的值。在一个长为n的序列中,堆排序的过程是从下标为n/2开始和其子节点中选择最小值,如果孩子节点的值更小,则会与父节点进行交换。不稳定举例如下
     序列1,2,3,2',经堆排序后的结果为1,2',2,3
     1          2'           3         
     / \         / \           / \
   2  3      2  3       2  2'
  /            /            /
 2'         1           1
     因此堆排序是不稳定的。


总结

综上,稳定排序有:冒泡排序、直接插入排序、归并排序和基数排序
不稳定排序有:简单选择排序、快速排序、希尔排序和堆排序
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值