导读

信息学能够有助于孩子未来工作发展,提升孩子的综合能力。


上节课我们讲了几个经典的排序算法,今天这节课我们深入了解另外的排序算法。


1 回顾

前面的一节课,我们学了几种排序算法,包括:


插入排序:直接插入排序,折半插入排序,希尔排序


交换排序:冒泡排序,快速排序


因为我们后面要详细分析每种算法,所以要深刻了解算法本身,才能更好理解后续的分析过程,下面我们简单回顾一下每种排序的思想。


1 插入排序

插入排序是将无需的元素不断插入到有序的序列中,直到所有的都有序为止。


直接插入排序就是从一个元素有序开始,然后将后面的元素从前面有序的序列中的最后一个元素开始比较,然后一直往前比较,直到找到合适的位置或者找到最开头。


折半插入排序优化了上面插入排序的对比过程,将n级的查找过程降低为对数级。但是移动元素的过程并没有优化。


希尔排序是保证间隔有序,然后不断缩小间隔大小,直到间隔为1。希尔排序是为了在比较短的时间内,让整体尽可能趋向于有序。

2 交换排序

交换排序是通过交换元素的位置实现的排序。其实本质上所有的排序算法都是通过交换元素的位置实现的。在分类中,还是会分不同的类别。


冒泡排序是不断比较相邻两个元素,如果不是有序的,就交换位置,直到所有的都有序为止。



快速排序是一个递归算法,选择一个集合中的一个元素,按照从小到大排序就是将小的放在它的左边,将大的放在它的右边,然后对每一个小部分依然采取上面的策略,直到剩下小于等于一个元素。这样整体就有序了。

2 选择排序

在这一小部分,我们来学习选择排序!


选择排序是选择一个元素,和其他元素比较,比较完一轮后,这个元素就在其最终位置了。

1 简单选择排序

简单选择排序就是我们前面讲的那个示例。


我们选择第一个和后面的每个元素比较,如果比后面的元素大,那么就要交换。


上面的操作做完以后,最小的就会在第一个位置了。


然后第二个再和后面的每个元素比较,如果比后面的元素大,那么就要交换。


上面的操作做完以后,次小的就会在第二个位置了。


以此类推,直到倒数第二个数据和最后一个数据比较完,两个数据位置确定。


2 堆排序

讲堆排序,其实应该先讲树。但是由于我们还没有讲到树,所以在这里,我们只讲最基本的,等以后讲了树,再讲深入的内容。


首先我们先来简单的看一下二叉树:


信息学集训 | 11 经典排序算法思想精讲2_父节点


从A节点指向了B和C节点,A节点是B和C的父节点,B和C分别是A的左子节点和右子节点。


信息学集训 | 11 经典排序算法思想精讲2_父节点_02


上面这幅图中,D和E分别是B的左右子节点,C,D,E没有子节点,我们称之为叶子结点,A节点没有父节点,是根节点。既有子节点,又有父节点,就是中间节点。


满二叉树是指层数为n层的二叉树,所有的位置全部填满,无法再加入新的节点,如果要加入新的节点,二叉树的层数就会+1。也就是说:所有的叶子结点必须在同一层,并且叶子节点的个数为:2^(n-1)。只要一个节点不是叶子结点,必然有两个子节点:


信息学集训 | 11 经典排序算法思想精讲2_父节点_03


完全二叉树是指一个节点在完全二叉树中的位序和在其对应的满二叉树中的位序是一致的。就比如上面的第二幅图,ABCDE五个节点在满二叉树中的位置和在其本身的位置是同一个位置,那么这棵树就是完全二叉树。


但是下面这一棵树不是:


信息学集训 | 11 经典排序算法思想精讲2_子节点_04


E节点在满二叉树应该对应到B的右子节点,但是它在这棵二叉树中却在C的左子节点。


也就是说,想要在一个节点插入数据,他前面的每一个位置都必须要插满才行。


堆就属于完全二叉树,但是堆还有一个额外的性质,父节点的值要同时大于等于(或同时小于等于)其所有子节点的值。我们将其分为:


大根堆:父节点的值要同时大于等于其所有子节点的值;
小根堆:父节点的值要同时小于等于其所有子节点的值;


我们以大根堆为例,因为每个父节点都大于子节点,以此类推,根节点是最大的。


信息学集训 | 11 经典排序算法思想精讲2_c++_05


比如上面这幅图,我们要想插入一个新的节点,就要先找到位置,应该放在4的左子节点。然后4比8小,4和8交换:


信息学集训 | 11 经典排序算法思想精讲2_父节点_06


因为有交换,所有8和7要比较。8比7大,所以8和7要交换:


信息学集训 | 11 经典排序算法思想精讲2_c++_07


然后8和9比较,9大,就不要交换了,堆排序结束:


信息学集训 | 11 经典排序算法思想精讲2_子节点_08


但是我们只是构成堆,但是从大到小的排序序列还没得到。接下来就是输出序列的过程。


首先,根节点是最大值,输出。就剩下了下面的内容:


信息学集训 | 11 经典排序算法思想精讲2_父节点_09


我们将最后一个节点(4)当成这棵二叉树的根节点:


信息学集训 | 11 经典排序算法思想精讲2_子节点_10


前面构建堆的过程是从下往上的构建,现在我们要从上往下。一种做法是,和两个子节点都比较,并选择最大的子节点交换(因为和最大的子节点交换,最大的子节点比另外一个子节点大,就不会影响另外一个子节点,也就是说下图中右边的就不用考虑了。):


信息学集训 | 11 经典排序算法思想精讲2_父节点_11


然后继续4和两个子节点比较并和最大子节点交换:


信息学集训 | 11 经典排序算法思想精讲2_父节点_12


这样又重新构成了大根堆。然后我们就可以将根节点输出。


然后我们再将最后一个节点放在根节点,然后再按照上面的放法进行构建堆:


信息学集训 | 11 经典排序算法思想精讲2_子节点_13


得到新的堆如下:


信息学集训 | 11 经典排序算法思想精讲2_子节点_14


然后我们将根(7)输出,然后再将5放在根的位置继续上述操作。


堆排序其实就是先将所有节点不断加入到堆中,也就是从下往上构建堆,输出过程就是输出根节点,并将最后的节点当作根节点,然后从上往下构建堆

3 其他常见排序

最后我们来看另外两个排序。

1 归并排序

归并排序我们这里指的是二路归并排序(多路归并排序是外部排序);


我们以一个序列为例:


1,5,6,9,4,8,2,3,7


上面是最初的序列,然后,我们两个归并为一个,并从小到大排序:


【1,5】【6,9】【4,8】【2,3】【7】


然后再合并:


【1,5,6,9】【2,3,4,8】【7】


然后再合并:


【1,2,3,4,5,6,8,9】【7】


最后合并:


【1,2,3,4,5,6,7,8,9】


上面的是归并的思想,重点是排序过程中怎么合并两个部分,我们以下面的两个为例:


【1,5,6,9】【2,3,4,8】


要想合并,我们就从两个部分的第一个元素开始,1小,存下来:


1
【5,6,9】【2,3,4,8】


然后2和5比,将2存下来:


1,2
【5,6,9】【3,4,8】


然后依次比较每一部分的第一个元素,把小的存到上面去:


1,2,3
【5,6,9】【4,8】


1,2,3,4
【5,6,9】【8】


1,2,3,4,5,6
【9】【8】


1,2,3,4,5,6,8,9


2 基数排序

基数排序是按照整数的每一位进行排序,例如我们有如下的数:


123,452,628,852,991,520


我们先按照个位从小到大排序:


520,991,452,852,123,628


然后再按照十位从小到大排序:


520,123,628,452,852,991


然后再按照百位从小到大排序:


123,452,520,628,852,991


4 作业

本节课的作业,就是复习上面的所有知识,将所讲的所有排序算法思想进行总结,并完成下面的题目!

1 实现归并排序

实现归并排序算法;



AI与区块链技术

信息学集训 | 11 经典排序算法思想精讲2_子节点_15

长按二维码关注