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一个桶,然后在桶内完成排序。

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

posted @ 2020-03-20 15:54  土堆碎念  阅读(307)  评论(0编辑  收藏  举报