排序算法——比较与代码汇总,对数器使用

排序算法1——图解冒泡排序及其实现(三种方法,基于模板及函数指针)
排序算法2——图解简单选择排序及其实现
排序算法3——图解直接插入排序以及折半(二分)插入排序及其实现
排序算法4——图解希尔排序及其实现
排序算法5——图解堆排序及其实现
排序算法6——图解归并排序及其递归与非递归实现
排序算法7——图解快速排序(两种主元选择方法)以及CUTOFF时间测试
排序算法8——图解表排序
排序算法9——图解桶排序及其实现
排序算法10——图解基数排序(次位优先法LSD和主位优先法MSD)
排序算法——比较与代码汇总,对数器使用


文章目录

  • 排序算法效率比较
  • 时间复杂度最低的方法——基数排序
  • 具有O(N^2^)时间复杂度的方法——简单选择、直接插入、冒泡排序
  • 具有O(Nlog~2~N)时间复杂度的方法
    • 1)堆排序
    • 2)快速排序
    • 3)归并排序
  • 代码总结
    • 一、基于比较的排序
      • 1. 冒泡排序
      • 2. 选择排序
      • 3. 插入排序
      • 4. 归并排序
      • 5. 快速排序
      • 6. 堆排序
    • 二、非基于比较的排序
      • 1. 桶排序
      • 2. 计数排序
      • 3. 基数排序
  • 总结
  • 对数器

排序算法效率比较

不存在绝对意义上最佳的方法,这些排序方法分别适用于不同的条件下

排序方法 平均时间复杂度 最坏情况下时间复杂度 额外空间复杂度 稳定性
简单选择排序 O(N2 O(N2 O(1) 不稳定
冒泡排序 O(N2 O(N2 O(1) 稳定
直接插入排序 O(N2 O(N2 O(1) 稳定
希尔排序 O(Nd),1 O(N2 O(1) 不稳定
堆排序 O(NlogN) O(NlogN) O(1) 不稳定
快速排序 O(NlogN) O(N2 O(logN) 不稳定
归并排序 O(NlogN) O(NlogN) O(N) 稳定
基数排序 O(D(N+R) O(D(N+R) O(N+R) 稳定

时间复杂度最低的方法——基数排序

它借助O(N+R)辅助空间严格限制的元素数据类型,仅需要O(D(N+R))的时间复杂度
适用于处理数量大、关键字取值范围有限的序列。同时,它是稳定的排序。

除基数排序外,其他的方法都是建立在比较和交换操作上的
决定它们性能的是比较、交换(主要是比较)的次数是否需要额外空间保存临时值

具有O(N2)时间复杂度的方法——简单选择、直接插入、冒泡排序

元素规模N较小或基本有序时,它们是比较好的排序方法。
简单选择排序是不稳定的,直接插入和冒泡排序是稳定的。

具有O(Nlog2N)时间复杂度的方法

1)堆排序

在栈顶元素输出后需要寻找下一个堆顶元素,在寻找的过程中不断将问题规模减小
堆排序在空间复杂度上表现出色,仅需要常数个额外空间

2)快速排序

在寻找主元以后,序列划分为两个部分,两个部分内部各自进行比较交换,两个部分之间没有进行比较
然而,在最坏情况下,快速排序可能导致O(N2)的时间复杂度
另外,快速排序需要O(log2N)深度的栈空间

3)归并排序

始终将规模减半再进行排序,在规模为N时再进行复杂度为O(N)的归并操作
归并排序需要O(N)的额外空间

代码总结

一、基于比较的排序

1. 冒泡排序

特点:每次冒泡能得到一个余下数组中最大的数放在end的位置上,若没有交换,说明数组已经有序。
时间复杂度:第一趟N次,第二趟N-1次…第N趟1次,O(N2
空间复杂度:O(1)

排序算法——比较与代码汇总,对数器使用_第1张图片

2. 选择排序

特点:
第一轮:0到N-1找一个最小的放在0位置
第一轮:1到N-1找一个最小的放在1位置

时间复杂度:O(N2
空间复杂度:O(1)
排序算法——比较与代码汇总,对数器使用_第2张图片

3. 插入排序

时间复杂度:O(N2
空间复杂度:O(1)
排序算法——比较与代码汇总,对数器使用_第3张图片
或者是
排序算法——比较与代码汇总,对数器使用_第4张图片

4. 归并排序

时间复杂度:O(N*logN)
额外空间复杂度:O(N)
排序算法——比较与代码汇总,对数器使用_第5张图片
排序算法——比较与代码汇总,对数器使用_第6张图片

5. 快速排序

时间复杂度:O(N*logN)
额外空间复杂度:O(logN)
排序算法——比较与代码汇总,对数器使用_第7张图片

6. 堆排序

初始化建堆的时间复杂度为O(n),排序重建堆的时间复杂度为nlog(n),所以总的时间复杂度为O(n+nlogn)=O(nlogn)
排序算法——比较与代码汇总,对数器使用_第8张图片

二、非基于比较的排序

与被排序的样本的实际数据状况有关,实际中并不常用
时间复杂度O(N),额外空间复杂度O(N),是稳定的排序

1. 桶排序

思路:

  1. N个数,找N个数中的最大值,分maxValue+1个桶
  2. 统计每个元素出现的次数
  3. 只要桶里有元素,就用这些元素重构原始数组

排序算法——比较与代码汇总,对数器使用_第9张图片

2. 计数排序

总结起来就是一个萝卜一个坑
比如有20个1-20的数,我就准备一个长度为20的数组,统计里面出现的个数(词频表),然后就可以不要原数组,重构一个数组,比如1出现了7次,我就放7个1在前面。

3. 基数排序

如果数据量比较大,有40亿个数,你就不能准备一个40亿大小的数组,因为实在太慢了。
这样你就会用到基数排序。

总结

基础类型——快排(不用管稳定性)
自定义类型——归并排序(因为要考虑稳定性)
数据规模小——插入排序(常数项极低,N<60)

对数器

  1. 实现一个绝对正确即使复杂度不好的方法b
  2. 实现一个随机样本产生器:生成容量随机和元素大小随机的数组
  3. 实现比对的方法:判断两个数组是否相等
  4. 把方法a和方法b比对很多次来验证方法a是否正确
  5. 如果有一个样本使得比对出错,打印样本分析是哪个方法出错
  6. 当样本数量很多时比对测试依然正确,可以确定方法a已经正确

你可能感兴趣的:(基础算法)