排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。
排序算法,就是如何使得记录按照要求排列的方法。排序算法在很多领域得到相当地重视,尤其是在大量数据的处理方面。一个优秀的算法可以节省大量的资源。在各个领域中考虑到数据的各种限制和规范,要得到一个符合实际的优秀算法,得经过大量的推理和分析
十种常见排序算法可以分为两大类:
- 比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此也称为非线性时间比较类排序。
- 非比较类排序:不通过比较来决定元素间的相对次序,它可以突破基于比较排序的时间下界,以线性时间运行,因此也称为线性时间非比较类排序。
相关概念:
- 稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面。
- 不稳定:如果a原本在b的前面,而a=b,排序之后 a 可能会出现在 b 的后面。
- 时间复杂度:对排序数据的总的操作次数。反映当n变化时,操作次数呈现什么规律。
- 空间复杂度:是指算法在计算机内执行时所需存储空间的度量,它也是数据规模n的函数。
序号 | 排序算法 | 平均时间复杂度 | 最坏时间复杂度 | 最优时间复杂度 | 空间复杂度 | 排序方式 | 稳定性 | 复杂性 |
---|---|---|---|---|---|---|---|---|
01 | 快速排序/Quick Sort | O(nlogn) | O(n2) | O(nlogn) | O(logn) ~ O(n) | In-place | 不稳定 | 较复杂 |
02 | 归并排序/Merge Sort | O(nlogn) | O(nlogn) | O(nlogn) | O(n) | Out-place | 稳定 | 较复杂 |
03 | 堆排序/Heap Sort | O(nlogn) | O(nlogn) | O(nlogn) | O(1) | In-place | 不稳定 | 较复杂 |
04 | 希尔排序 | O(nlogn) ~ O(n2) | O(n2) | O(n1.3) | O(1) | In-place | 不稳定 | 较复杂 |
05 | 冒泡排序 | O(n2) | O(n2) | O(n) | O(1) | In-place | 稳定 | 简单 |
06 | 插入排序 | O(n2) | O(n2) | O(n) | O(1) | In-place | 稳定 | 简单 |
07 | 选择排序 | O(n2) | O(n2) | O(n2) | O(1) | In-place | 不稳定 | 简单 |
08 | 计数排序 | O(n+k) | O(n+k) | O(n+k) | O(k) | Out-place | 稳定 | 较复杂 |
09 | 桶排序 | O(n+k) | O(n2) | O(n+k) | O(n+k) | Out-place | 稳定 | 较复杂 |
10 | 基数排序 | O(n×k) | O(n×k) | O(n×k) | O(n+k) | Out-place | 稳定 | 较复杂+ |
注释:
n: 数据规模
k: “桶”的个数
In-place: 占用常数内存,不占用额外内存
Out-place: 占用额外内存
一、排序算法的稳定性
排序算法的稳定性:稳定排序算法会让原本有相等键值的纪录维持相对次序。也就是如果一个排序算法是稳定的,当有两个相等键值的纪录R和S,且在原本的列表中R出现在S之前,在排序过的列表中R也将会是在S之前。
假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,则称这种排序算法是稳定的, 否则称为不稳定的。
当相等的元素是无法分辨的,比如像是整数,排序方法是稳定性排序方法还是不稳定排序方法并不会造成太大的问题。然而,假设以下的数对将要以他们的第一个数字来排序。
(4, 1) (3, 1) (3, 7)(5, 6)
在这个状况下,有可能产生两种不同的结果,一个是让相等键值的纪录维持相对的次序,而另外一个则没有:
(3, 1) (3, 7) (4, 1) (5, 6) (维持次序)
(3, 7) (3, 1) (4, 1) (5, 6) (次序被改变)
- 不稳定排序算法可能会在相等的键值中改变纪录的相对次序,但是稳定排序算法从来不会如此。
- 不稳定排序算法可以被特别地实现为稳定。作这件事情的一个方式是人工扩充键值的比较,如此在其他方面相同键值的两个对象间之比较,(比如上面的比较中加入第二个标准:第二个键值的大小)就会被决定使用在原先数据次序中的条目,当作一个同分决赛。然而,要记住这种次序通常牵涉到额外的空间负担。