排序(Sort)

前言

排序算法一直是计算机核心算法之一,人们也在一直研究它们。现实情况中,直接依赖排序算法的事物有很多,间接依赖排序算法的事物有更多。
所以研究排序算法对于程序员来说很重要。

收获

排序算法不是相互孤立的,互相协作反而可以提高性能

例如快速排序,在分割(partition)之前,如果需要分割的区间过短(比如3),可以对该分割区间进行插入排序而不是继续快速排序。原因是对于小数组来说,快速排序要比插入排序慢(在数组规模较小的情况下,不能忽略渐进时间的常数项)。

在数据规模较小的情况下,不能忽略算法分析中忽略的常数项

考虑一种很极端的情况:只有两个数,分别用插入排序和快速排序排序。
从渐进时间来看,插入排序渐进时间为 n2 ,快速排序渐进时间为 nlnn
而从实际程序来看,插入排序最多只需要一次比较和交换,而快速排序至少需要两次比较和一次交换,显然插入排序完胜快速排序。

快速排序并不是完美的排序算法

  • 数组有序的时候,快速排序很慢,渐进时间为 nlnn
  • 对于小数组来说,快速排序的比较和交换次数过多,速度变慢
    其实没有任何算法可以堪称完美,在一方面出色,在另一方面就逊色。

既要考虑到内存访问,也要考虑到缓存访问

对于堆排序,时间复杂度 nlnn ,空间复杂度 n ,看似完美,实则不然。其余的算法存储空间为连续的,可以统一装入缓存,而堆排序是跳跃着访问元素,无法一次性将所需元素装入缓存。在实际应用中,堆排序还可能偏慢。

排序算法比较

算法 平均时间复杂度 空间复杂度 代码复杂度 稳定性 递归 适用规模 有序适应
插入排序 n2 0
归并排序 nlnn n
快速排序 nlnn 0
堆排序 nlnn 0

排序算法特殊用法

插入排序

希尔排序,将插入排序的步长(1)扩大,在慢慢减少至最小步长(1)。希尔排序很大程度上提高了插入排序的速度。希尔排序虽然很有用,但是具体提高速度的原因至今科学家都无法证明。

归并排序

对于小数组的归并,可以用插入排序。

快速排序

  • 分割之前判断,若分割的区间很小,可以不去分割和排序,而是直接用插入排序排序
  • 若数组重复元素较多,改进快速排序算法,变为三路划分快速排序
  • 求第 k 个最大值的时候,可以根据快速排序的性质(每个分割过的坐标都是元素应该最终存在数组的位置),求解第 k <script type="math/tex" id="MathJax-Element-15">k</script> 个最大值。

    堆排序

    可以用于优先队列(Priority Queue)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值