排序算法 之四 分类、时间/空间复杂度、如何选择

写在前面

  现在网上关于排序算法的文档不计其数,为什么要写这篇文章呢?主要是因为一些算法虽然在平时有用到,但是从来没有细细整理过,没有个统一、整体的认识。写这篇文章一来是进行一下总结,二来趁机再系统的学一下各排序算法!

分类

根据不同的分类标准,排序算法的分类有很多种,下面重点介绍几种。

  • 根据待排序的数据量大小不同,使得排序过程中所涉及的存储器不同,可以分为:
    在这里插入图片描述

    • 内部排序: 待排序的内容在内存中就可以完成。
    • 外部排序: 待排序的记录存储在外存储器上,待排序的数据无法一次装入内存,需要在内存和外部存储器之间进行多次数据交换,以达到排序所有数据的目的。
        外部排序最常用的算法是 多路归并排序,即将原始数据分解成多个能够一次性装入内存的部分,分别把每一部分调入内存完成排序。然后,对已经排序的子文件进行多路归并排序。这种归并方法可分为两个不同的阶段:
      1. 采用适当的内部排序方法对划分好的每个数据片段进行排序,将排好序的片段(称为归并段)写到外部存储器中(通常由一个可用的磁盘作为临时缓冲区),这样临时缓冲区中的每个归并段的内容是有序的。
      2. 利用归并算法,归并第一阶段生成的归并段,直到只剩下一个归并段为止。
  • 根据排序关键字可能出现重复,根据重复关键字的排序情况可分为:
    在这里插入图片描述

    • 稳定排序: 排序后重复关键字记录的相对次序保持不变。例如,如果a原本在b前面,而 a=b,排序之后a仍然在b的前面。
    • 不稳定排序: 排序后重复关键字记录的相对次序可能改变。例如,如果a原本在b的前面,而 a = b,排序之后 a 可能会出现在 b 的后面。
  • 根据排序的实现策略可分为:
    在这里插入图片描述

    • 比较类排序: 依赖于比较和交换来将元素移动到正确的位置上,由于其时间复杂度不能突破O(nlogn),因此也称为 非线性时间比较类排序
    • 非比较类排序: 不通过比较来决定元素间的相对次序,它可以突破基于比较排序的时间下界,以线性时间运行,因此也称为 线性时间非比较类排序
      对于线性时间排序,它的运行时间往往与它处理的数据元素个数成正比,即为O(n)。线性排序的缺点是它需要依赖于数据集合中的某些特征,所以我们并不是在所有的场合都能够使用它。

时间/空间复杂度

在这里插入图片描述

如何选择

  排序算法可以说是一项基本功,是《数据结构与算法》中最基本的算法之一。实际工作中或多或少都会用到那么一两个。合理选择一种排序算法,对于一个项目程序的设计是非常重要的!
  选择合适算法就和选择对象一样,最适合的才是最好的! 影响选择排序算法的因素有很多,例如时间复杂度和空间复杂度可以说是个重要的参考标准。但是,平均时间复杂度低的算法并不一定就是最优的选择。相反,有时候,平均时间复杂度高的算法反而更加适合自己的实际情况。一般来说,主要就是依据以下这几点:

  • 数据规模: 在实际项目中,通常这是第一个要考虑的点。通过对于数据规模的把握,可以缩小我们算法的选择范围。在很小的数据量时,就现在的处理器水平而言,选择绝大多数算法都看不出差异!一旦数据量变大,算法的差异性就会体现的越明显。
  • 时间复杂度: 在绝大多数情况下,这都是一个决定性的因素。因为在实际情况下,最看重的往往就是算法的执行效率。常见的算法时间复杂度由小到大依次为:Ο(1)<Ο(log2n)<Ο(n)<Ο(nlog2n)<Ο(n2)<Ο(n3)<…<Ο(2n)<Ο(n!)
  • 空间复杂度: 这点通常不是我们首先需要考虑的条件。甚至于计算下编程我们根本不考虑这点。但是,在嵌入式编程中还是有必要考虑的。
  • 算法的难易程度: 想想在嵌入式编程中,去实现一个最佳归并树是否有必要!

当然,在实际情况下,通常需要多种排序算法来组合使用!综合以上三点,当数据量较大,则应采用时间复杂度为O(nlog2n)的排序方法。例如,快速排序、堆排序或归并排序序。当数据量很小时,选择最简单的算法即可!

ZCShouEXP CSDN认证博客专家 砖家 码字员 没了
进步始于交流,收获源于分享!进步始于交流,收获源于分享!进步始于交流,收获源于分享!进步始于交流,收获源于分享!进步始于交流,收获源于分享!
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页