欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

归并排序

程序员文章站 2024-03-15 17:37:12
...

一:定义

作为选择排序的改进版,堆排序可以把每一趟元素的比较结果保存下来,以便我们在选择最小/大元素时对已经比较过的元素做出相应的调整。

简单总结下堆排序的基本思路:

  a.将无需序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆;

  b.将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端;

  c.重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序。

coding

:

二:堆排序算法

作为选择排序的改进版,堆排序可以把每一趟元素的比较结果保存下来,以便我们在选择最小/大元素时对已经比较过的元素做出相应的调整。

堆排序是一种树形选择排序,在排序过程中可以把元素看成是一颗完全二叉树,每个节点都大(小)于它的两个子节点,当每个节点都大于等于它的两个子节点时,就称为大顶堆,也叫堆有序; 当每个节点都小于等于它的两个子节点时,就称为小顶堆。

归并排序 

归并排序

归并排序

下面是我们要保存在数组中的堆的形式

归并排序

回到顶部

二:堆排序算法

1.将长度为n的待排序的数组进行堆有序化构造成一个大顶堆
 
2.将根节点与尾节点交换并输出此时的尾节点
 
3.将剩余的n -1个节点重新进行堆有序化
 
4.重复步骤2,步骤3直至构造成一个有序序列

回到顶部

三:图解演示,构造堆(大顶堆)

{5, 2, 6, 0, 3, 9, 1, 7, 4, 8}

归并排序

在构造有序堆时,我们开始只需要扫描一半的元素(n/2-1 ~ 0)即可,为什么?

因为(n/2-1)~0的节点才有子节点,如图1,n=8,(n/2-1) = 3 即3 2 1 0这个四个节点才有子节点

第一次找到[n/2]处,进行构造:

归并排序

我们比较父节点,左右孩子结点的大小,将最大的作为堆顶

第二次,我们对上次找到位置-1即可,找到结点0,对其左右孩子比较,构造这三个结点的最大堆

归并排序

第三次,我们找到结点6,要对其进行构造,结果如下

归并排序

第四次(重点),我们不止要构造双亲和左右孩子,我们还要比较其孩子结点为根的堆是否正确,不然我们需要进行调整

归并排序

我们发现将8,7,2三个结点变为了最大堆,但是其中2,3子树不再是一个最大堆,我们需要对其修改

归并排序

第五次:选取结点9进行构造

归并排序

发现以结点5为根的子树不是最大堆,我们需要进行调整

归并排序

完成最大堆的构建

归并排序

回到顶部

四:图解演示:堆排序(堆存储在数组中)

第一步:将最大值和最后的一个元素交换

归并排序

第二步:将剩余的结点再次进行堆构造

归并排序

第三步:参照第一步

归并排序

按照上面循环,最终结果为

归并排序