版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_38120325/article/details/84585460
排序算法:
非线性时间比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nLogn);
线性时间非比较类排序:不通过比较来决定元素间的相对次序,它可以突破基于比较排序的时间下界,以线性时间运行,因此成为线性时间非比较类排序;
分类:
复杂度:
相关概念:
稳定:不会打乱符合规则的原有排序;
不稳定:有可能打乱符合规则的原有排序;
算法介绍:
- 冒泡:
- 比较相邻的两个元素,根据规则调换位置
- 选择(表现最稳定的排序算法之一.时间复杂度永远是o(n平方),数据规模越小越好,不占用额外的内存空间)
- 依次找出最边界的值进行排序
- 插入排序(只需用到O(1)的额外空间的排序)
- 默认第一个元素已经排序
- 之后的元素,通过比较新元素与每一个已排序元素,将新元素放到合适的位置
- 希尔排序第一个突破(O(n平方))
- 将大序列分割为小序列,对各个表进行插入排序,比较最后一个元素与第一个元素;
- 归并排序(归并排序是一种稳定的排序方法。和选择排序一样,归并排序的性能不受输入数据的影响,但表现比选择排序好的多,因为始终都是O(nlogn)的时间复杂度。代价是需要额外的内存空间。)
- 将一个大的序列看做是length个小序列,然后开始归并;
- 快速排序:
- 设定基准和数组下标,从前往后找比基准大和基准换位置,从后找比基准小的和基准换位置,知道数据索引碰头,重复
- 堆排序:利用堆的数据结构设计的排序算法:子节点的键值或索引总是小于它的父节点:
- 组成二叉树,将当前全树最大值交换到顶级父节点,与最后一个节点的子节点交换,将最后一个子节点从二叉树中剔除;循环此过程直到没有二叉树;
- 计数排序: 计数排序是一个稳定的排序算法。当输入的元素是 n 个 0到 k 之间的整数时,时间复杂度是O(n+k),空间复杂度也是O(n+k),其排序速度快于任何比较排序算法。当k不是很大并且序列比较集中时,计数排序是一个很有效的排序算法。
- 找出要排序的数据的最大的元素和最小的元素,创建一个新的数据空间,然后将每一个元素存入新空间,反向填充 从最小的元素角标开始填充数组,每个元素填充的次数为放入的次数;
- 桶排序:利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。桶排序最好情况下使用线性时间O(n),桶排序的时间复杂度,取决与对各个桶之间数据进行排序的时间复杂度,因为其它部分的时间复杂度都为O(n)。很显然,桶划分的越小,各个桶之间的数据越少,排序所用的时间也会越少。但相应的空间消耗就会增大。
- 确定最大值和最小值
- 初始化桶个数的空间
- 根据映射函数将元素放入对应的桶
- 每个桶内排序(方法不确定)
- 将排序好的桶拼接起来
- 基数排序: 基数排序基于分别排序,分别收集,所以是稳定的。但基数排序的性能比桶排序要略差,每一次关键字的桶分配都需要O(n)的时间复杂度,而且分配之后得到新的关键字序列又需要O(n)的时间复杂度。假如待排数据可以分为d个关键字,则基数排序的时间复杂度将是O(d*2n) ,当然d要远远小于n,因此基本上还是线性级别的。
- 按照低优先级先排序,按照高优先级再排序,直到最高优先级,然后在类似计数排序
时间复杂度:执行算法所需要的计算工作量,算法执行的次数
空间复杂度:执行算法所需要的内存空间