常见排序算法总结

1. 选择排序

  1. 找到数组中最小的那个元素
  2. 将它与数组的第一个元素交换位置
  3. 再次,在剩余的元素中找到最小的元素,如此反复。

2. 插入排序

  1. 选择第二个元素。
  2. 将它从后往前依次与之前的元素比较
  3. 如果小于之前的元素,则交换两个元素位置,并继续从后往前比较之前元素,直至到第一个元素或者出现大于的情况位置
  4. 如果大于之前的元素,则终止比较。并选择下一个元素,重复执行2-4步骤。

适用场景

对于部分有序的数据十分高效,也很适合小规模数组。

3. 希尔排序

  • 希尔排序的思想是使数组中任意间隔为h的元素都是有序的。
  • 只需要在插入排序的代码中将移动元素的距离由1改为h即可。

适用场景

和选择排序以及插入排序不同,希尔排序也可以用于大型数组,它对任意排序的数组表现也很好。

4. 归并排序

自顶向下的归并排序

  • 先(递归地)将要排序的数组分层两半分别排序,然后将结果归并起来。
  • 实现归并的一种直截了当的办法是将两个不同的有序数组归并到第三个数组中。
  • 如果要原地归并,可以将涉及的所有元素复制到一个辅助数组中,再把归并的结果返回原数组中。

自底向上的归并排序

  • 先归并那些微型数组,然后再成对归并得到的子数组。
  • 比较适合用链表组织的数据

5. 快速排序

  1. 随意地取a[lo]作为切分元素k。
  2. 分别从数组的左右进行扫描,从左边找到第一个大于k的,从右边找到第一个小于k的,将他们交换
  3. 重复2的过程,直至i,j相遇,或遇到两端。
  4. 对换a[lo]和a[j],此时j为切分的位置。
  5. 对(lo,j-1)和(j+1,hi)分别递归调用排序方法。

优势

  • 实现简单,适合各种不同的输入且在一般应用中比其他算法快得多,并且是原地排序。
  • 归并排序和希尔排序一般都比快排慢,原因是它们还在内循环中移动数据。

6. 堆排序

优先队列

  • 优先队列是一种数据,支持两种操作:删除最大元素和插入元素。
  • 数据结构二叉堆能够很好地实现优先队列的基本操作。
  • 当一棵二叉树的每个结点都大于等于它的两个子结点时,它被称为堆有序。
  • 二叉堆是一组能够用堆有序的完全二叉树排序的元素,并在数组中按照层级存储。
  • 多叉堆需要在树高(logdN)和在每个结点的d个子结点找到最大者的代价之间找到折中。

堆的算法

  • 插入元素:将新元素加到数据末尾,增加堆的大小并让这个新元素上浮到合适的位置。
  • 删除最大元素:从数据顶端删除最大的元素并将数组的最后一个元素放到顶端,减小堆的大小并让这个元素下沉到合适的位置。

堆排序

  1. 构造堆:从N/2的位置开始从右至左用sink()构造子堆。
  2. 下沉排序:
    1. 移除最大的元素(移除过程包括下沉操作),放置在数组末尾。由于移除后,堆所占的数组长度-1,末尾的位置不属于堆,可用于存放已排序的数字。
    2. 移除当前堆最大的元素(整个数组里第二大的元素),放置在数组倒数第二的位置。
    3. 以此类推,直至堆为空,此时数组已排序。

7. 常见问题

为什么java.util.Arrays.sort()要对原始类型采用DualPivotQuicksort,而对引用类型采用TimSort

  1. 快排是不稳定的,相同的元素可能在排序中会改变位置,这对于原始类型来说没什么关系,但是对于引用类型,可能在一些程序会有问题。
  2. 归并排序需要复制一份数组,对于引用类型来说,被引用的对象通常会比引用数组本身耗费更多的内存,通常情况下关系不大;但是对于原始类型来说,复制数组会导致双倍的内存占用。
  3. 快排是最快的通用排序算法。

稳定性

如果一个排序算法能够保留数据中的重复元素的相对位置则可以被称为是稳定的。
- 稳定的算法:插入排序、归并排序
- 不稳定的算法:选择排序、希尔排序、快速排序、堆排序

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值