2021-07-31

排序:利用数组将一组数据,按指定的顺序进行排列

分类:内部排序:将要处理的所有数据都加载到内部存储器中进行排序。(八种排序)

  • 插入排序:

    • 直接插入O(n2):将无序元素通过比较,插入有序空间
    • 希尔排序: 简单的插入排序每次只比较两个元素只能交换两个错位的元素,所以效率很低,希尔排序在此基础上通每次比较(并交换)相隔一定距离的元素,从而提高排序效率。
  • 选择排序:

    • 简单选择O(n2):找到数组中最小的元素,并和第一个元素进行交换,在剩下的元素中找到最小的元素,与数组中的第2个元素进行交换,如此往复,直到有序
    • 堆排序: 堆排序就是利用堆(优先队列)对序列进行排序,因为优先级最高的元素永远在堆顶,所以我们可以一直取堆顶元素然后重新生成堆直到有序。这个过程其实就是根据上面的冒泡排序,把找最优元素的任务交给了堆 来降低时间复杂度。
  • 交换排序:

    • 冒泡排序O(n2): 进行N-1次循环,在第k次循环中从0开始到N-k-1每次比较相邻的两个元素,看是否需要交换。
    • 快速排序: 和插入排序时一样,冒泡排序每次只比较相邻的两个元素,所以效率也会很低,如果我们每次取未排序的序列中的一个元素(称为主元)把未排序的序列分成两个子序列,其中一个全部小于主元,另一个全部大于主元,然后递归地进行这样的排序。
  • 归并排序: 顾名思义,归并排序就是根据归并操作的原理,把序列中的N个元素看成N个有序的子序列,每次合并两个相邻有序子序列,直到剩下一个长度为N的 序列,即为原序列排好序后的有序序列

    • 利用归并思想进行排序,采用了分治策略。
  • 基数排序: 是桶排序的延伸,排序时不止考虑单个关键字。其实就是单纯用一种关键字来排序效率低,我们可以对于在一种分类后子序列还能分为许多种子序列(也就是多层关键字)的情况用基数排序,也就是将单个整形关键字按某种基数分解为多关键字,再进行排序。

  • 堆排序:就是利用堆(优先队列)对序列进行排序,因为优先级最高的元素永远在堆顶,所以我们可以一直取堆顶元素然后重新生成堆直到有序

  • 外部排序:数据量过大,无法全部加载到内存中,需要借助外部存储进行排序。

    算法的时间复杂度O(f(n)):

    1. 事后统计法:先运行再统计:1.麻烦;2.不准确,必须在同一台计算机的相同状态下运行才能比较(不推荐)

    2. 事前估算法:分算法的时间复杂度来判断,复杂度是忽略常数的(指数级)
      时间频度T(n):算法花费的时间与算法中语句的执行次数成正比
      比如求连续数字之和:

      total = (1+end)*end/2; T(n) = 1;
      而常规的算法 T(n) = n+1; 1.忽略常数 2.忽略低次项 3.忽略系数
      计算时间复杂度的方法:
      1.常数项用1代替
      2.只保留最高阶项
      3.去除最高阶项的系数
      *对数阶logN < 线性阶n < 线性对数阶nlogN

    无论代码执行多少行,若没有循环等复杂结构,时间复杂度为O(1);
    while(i < n)i = i*2; 时间复杂度为logN
    消耗的时间随n的变换而变化 O(n)
    将时间复杂度为O(logN)的代码循环n边 nlogN
    双层for循环 O(n^2)
    i层for循环 O(n^i)

  • 空间复杂度:占用的储存空间大小(空间换时间):用户体验来看,更看中程序的执行速度

  • 稳定性:

    1. a原本在b的前面,而a=b,排序之后a仍在的前面,就是稳定的
    2. 若a可能出现在b的后面,就是不稳定的

    没有最好的算法,只有最合适的算法

  1. 当数据规模较小时候,可以使用简单的直接插入排序或者直接选择排序。
  2. 当文件的初态已经基本有序,可以用直接插入排序和冒泡排序。
  3. 当数据规模较大时,应用速度最快的排序算法,可以考虑使用快速排序。当记录随机分布的时候,快速排序平均时间最短,但是会出现最坏的情况,这个时候的时间复杂度是O(n^2),且递归深度为n,所需的占空间为O(n)。
  4. 堆排序不会出现快排那样最坏情况,且堆排序所需的辅助空间比快排要少,但是这两种算法都不是稳定的,要求排序时是稳定的,可以考虑用归并排序。
  5. 归并排序可以用于内部排序,也可以使用于外部排序。在外部排序时,通常采用多路归并,并且通过解决长顺串的合并,加上长的初始串,提高主机与外设并行能力等,以减少访问外存额外次数,提高外排的效率。
  6. 特殊的桶排序、基数排序都是稳定且高效的排序算法,但有一定的局限性:
    • 关键字可分解。
    • 记录的关键字位数较少,如果密集更好
    • 如果是数字时,最好是无符号的,否则将增加相应的映射复杂度,可先将其正负分开排序。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值