zoukankan      html  css  js  c++  java
  • 10. 排序算法思想概述及总结(精华)

    排序算法的常用种类

    初级排序

    • 选择排序
    • 插入排序
    • 希尔排序

    进阶排序

    • 快速排序
    • 归并排序
    • (二叉堆排序)堆排序

    非比较排序

    • 计数排序

    • 基数排序

    • 桶排序


    逆序对

    逆序对,是分析排序算法的一个重要知识点。既然评估排序算法,就要知道如何去描述数组的排序程序。

    逆序对,数组中两个逆序元素的对数。

    比如【1, 5, 3】,其中(5, 3)就是逆序的,所以这个数组的逆序对为1。

    那么一个数组的最好逆序对为0,最坏逆序对为 n(n-1)/2。

    因为逆序对是两两进行组合,所以每个元素能够跟其他 n-1 元素配对,因为两两重复,所以除以2。


    排序算法的基本思想(出现原因)

    选择排序

    选择数组中最小值,将其放入数组的最左边。

    放入数组的方式,分为移动插入和一直交换相邻元素。

    可以发现,每进行一次相邻交换,逆序对将会减一。

    时间复杂度:每进行一次操作,需要比较(n-k)个元素,找到最小的元素。然后移动最小元素所在位置到前面。所以时间复杂度为n平方。

    空间复杂度:无需其他空间。

    插入排序

    将数组分为排序和未排序两部分,每次从未排序部分选取一个元素,按顺序插入到已排序部分。

    想象你打牌的时候,手上拿的是已排序的拍,每次抓牌的时候,都是把抓到的牌(未排序)按顺序插入到手上已排序的牌中。

    插入的策略,也是交换相邻元素或者移动插入。每进行一个相邻交换,逆序对减一。

    时间复杂度:选取未排序元素的时间为常数,所以需要确认将其插入到排序元素中的时间。(这是关键)之前说过,每交换相邻元素,逆序对会减一,所以插入到排序元素的时间跟逆序对成正比。

    所以,可以很容易得出,最坏时间复杂度为(n-1)n/2,平均时间复杂度为(n-1)n/4,最好时间复杂度为1

    希尔排序

    希尔排序,间隔抽样子数组,对子数组完成排序。

    为什么叫初级排序呢

    (《算法》中将它们成为初级排序,也许是算法思想比较简单,时间复杂度比较高)

    我们发现一个特点,虽然思想是不一样的,但实现中,基本上都是采用交换相邻元素的特点来达到插入的目的。而且每次交换相邻元素,都会使得逆序对减一。所以很自然,这些思想会和逆序对成正比。


    快速排序

    快速排序,是选取一个元素,然后经过交换元素,保证选定元素的左边都小于它,右边元素都大于它。每次操作后,选定元素的位置就是排序后的位置。

    在实际算法中,我们可以看到,每交换元素的时候,逆序对减少的个数会大于等于1。这就是相较于初级算法的提升。

    归并排序

    归并排序,是分为多个子数组,再合并的方法。(不赘述)

    二叉堆排序

    一般利用堆,实际实现是利用数组的形式,进行维护top k的一种排序方法。


    非比较排序

    上面的方法,都是基于数与数的比较,来完成排序。而非比较排序,不需要比较数与数之间的关系。

    你只要知道你前面有多少人,你就可以确定你的位置,进而排序。

    计数排序

    计数排序,是记录每个位置上应该出现的数字,比如【1, 3, 4, 5】,我们就可以建立一个数组【1, 0, 1, 1, 1】,表示有1个1,0个2, 1个3, 1个4, 1个5。

    计数排序适用于相对集中的数据排序,如果【1, 100】, 那我们就要建立100位的计数数组。

    基数排序

    之前说了计数排序的弊端,那么基数排序是用来解决这个问题的。基数排序,从个位,十位,百位入手,对于个位进行计数排序,因为个位可能出现的数字最多只有10个,也就是基数。【1, 100】就被分为百位、十位、个位,三个基数排序。

    桶排序

    桶排序,可以大致理解位数据进行分块,但不是像归并排序那样随机分,而是有个相对顺序的区间,就比如100-90, 90-80一个桶,然后在桶内完成排序。

    这种情况适用于数据相对多,而且数据大小分布相对均匀的情况下。

  • 相关阅读:
    [原]关于在Python和C#之间消息传递的问题
    【原】为DevExpress的ChartControl添加Y轴控制 和 GridControl中指定列添加超级链接
    【原】使用Json作为Python和C#混合编程时对象转换的中间文件
    【原】在Matplotlib绘图中添加Latex风格公式
    【原】关于AdaBoost的一些再思考
    【原】使用Tkinter绘制GUI并结合Matplotlib实现交互式绘图
    使用C#+Linq+SQL快速开发业务
    oracle expdp导出时报 ora-39070:无法打开日志文件
    Oracle 关于expdp和impdp的应用实践
    IIS7启动优化
  • 原文地址:https://www.cnblogs.com/zhouzhiyao/p/12532235.html
Copyright © 2011-2022 走看看