【基础算法】排序算法简介

排序是对批量数据按照一定的顺序进行排列的操作。

 

一、学习排序算法的要点

学习排序算法,就是学习每一种算法的算法原理、代码实现,以及如何评价算法优劣。

 

二、评价排序算法的优劣

排序算法的优劣可以从以下 3 个方面进行评价:

  • 时间性能:最好、最坏、平均时间复杂度;

  • 内存占用:是否原地排序,原地排序算法,特指空间复杂度是 O(1) 的排序算法;

  • 稳定性:相等的数据,排序前后顺序是否有变化,顺序不变是稳定排序算法。

 

三、常用排序算法

排序算法 时间复杂度 空间复杂度 稳定性 算法核心
冒泡排序 O(n2) O(1) 稳定 比较交换
选择排序 O(n2) O(1) 不稳定 比较交换
插入排序 O(n2) O(1) 稳定 插入排序
希尔排序 O(n1.3) O(1) 不稳定 插入排序
归并排序 O(nlog2n) O(n) 稳定 比较合并
快速排序 O(nlog2n) O(1) 不稳定 比较交换
桶排序 O(n) O(n) 稳定 非比较
计数排序 O(n) O(n) 稳定 非比较
基数排序 O(n) O(n) 稳定 非比较

 

冒泡排序、选择排序,时间复杂度都是 O(n2),实际开发中应用并不多,学习的目的只是为了开拓思维。不过插入排序还是挺有用的,虽然时间复杂度也是 O(n2),但是算法思路有很大的优化空间,比如基于插入排序思想的希尔排序,效率高了很多。这三种排序算法,代码实现非常简单,可以用于小规模数据的排序

 

归并排序、快速排序,时间复杂度都是 O(nlog2n) ,它们用的都是分治思想,代码都通过递归来实现,适用于大规模数据排序。归并排序是一种在任何情况下时间复杂度都比较稳定的排序算法,缺点也很明显,即归并排序不是原地排序算法,空间复杂度是 O(n)。正是如此,它没有快排应用广泛。快速排序虽然最坏情况下的时间复杂度是 O(n2),但是平均情况下时间复杂度都是 O(nlog2n)。不仅如此,快速排序时间复杂度退化到 O(n2) 的概率非常小,可以通过合理地选择 pivot 来避免这种情况。

 

桶排序、计数排序、基数排序,对要排序的数据要求比较苛刻,应用不是非常广泛。但是如果数据特征比较符合这些排序算法的要求,那么会非常高效,时间复杂度可以达到 O(n)。桶排序和计数排序的排序思想非常相似,都是针对范围不大的数据,将数据划分成不同的桶来实现排序。基数排序要求数据可以划分成高低位,位之间有递进关系。比较两个数,只需要比较高位,高位相同的再比较低位。而且每一位的数据范围不能太大,因为基数排序算法需要借助桶排序或者计数排序来完成每一个位的排序工作。

 

四、有序度与逆序度

4.1 有序度

有序度是数组中具有有序关系的元素对的个数。有序元素对用数学表达式表示如下:

有序元素对:对于数组 arr,如果下标 i < j,那么 arr[i] <= arr[j]。

根据定义可知,数组 [4,5,6,3,2,1]  的有序度为 3,因为其有序元素对为 3 个,分别是:(4,5) (4,6) (5,6)。

倒序排列的数组,有序度为 0;完全有序的数组,有序度为 n(n-1)/2,比如,数组 [1,2,3,4,5,6]  的有序度为 15,这种完全有序数组的有序度叫做满有序度

 

4.2 逆序度

逆序度与有序度正好相反。用数学表达式表示如下:

逆序元素对:对于数组 arr,如果下标 i < j,那么 arr[i] > arr[j]。

数组 [4,5,6,3,2,1]  的逆序度为 12,因为其逆序元素对为 12 个,分别是:(4,3)(4,2)(4,1)(5,3)(5,2)(5,1)(6,3)(6,2)(6,1)(3,2)(3,1)(2,1)。

 

根据有序度、逆序度、满有序度的概念,可以得到一个公式:逆序度 = 满有序度 - 有序度

数组排序的本质,就是增加有序度,减少逆序度的过程,最后达到满有序度,排序完成。

 

posted @ 2023-10-04 17:15  有点成长  阅读(27)  评论(0编辑  收藏  举报