![b16bcb019cbbbe9aaafc7b02927e900a.png](https://img-blog.csdnimg.cn/img_convert/b16bcb019cbbbe9aaafc7b02927e900a.png)
优先队列
在学习堆和堆排序之前,我们需要了解什么是优先队列。乘坐飞机前你一定清楚这样一个场景,在候机厅排队登机时,我们会看到有专门的头等舱通道,持有头等舱机票的乘客可以不用排队就能直接登机,就好像他们有“特权”一样。
![bd8e16dcc61121c232c59cd3add7d1f3.png](https://img-blog.csdnimg.cn/img_convert/bd8e16dcc61121c232c59cd3add7d1f3.png)
我们可以认为,坐头等舱的乘客的优先级比坐普通经济舱的乘客要高。如果用计算机里的队列来描述的话,头等舱的乘客在出队时总是先于经济舱的乘客。于是,我们可以定义出一种新的抽象数据类型,优先队列(priority queue),即所有元素都按照优先级的大小出队。举个例子,假设一个数组为
堆
假设一个优先队列全由数字组成时,我们需要两个数组,一个用于存储数据,一个用于存储每个元素的优先级。所需要的存储量是普通数组的两倍,这显然是不可行的。另外,因为队列的出队操作只能严格地在队尾执行,所以每次出队的过程中,出队的元素必须要和队尾元素进行交换,然后再出队,并且每次出队后存储优先级的数组也要做出相应的变化才能够保证优先队列的性质,所以操作会非常麻烦。因此,我们还需要另寻他法,使优先队列的数据结构在操作上更简单。
![034176a32529a216fbf83269d0fa7863.png](https://img-blog.csdnimg.cn/img_convert/034176a32529a216fbf83269d0fa7863.png)
我们可以借助二叉树的性质,将优先级越高的元素放置在越靠近根节点的位置,换句话说就是位于层数越低的地方。堆(heap)就是一种将优先队列变换为了二叉树的数据结构。下面来介绍一下它的性质。
完全二叉树
堆是一棵完全二叉树。在数据结构那一节里,我们简单地提到了它。区分完全二叉树和非完全二叉树在于完全二叉树除了最后一层的节点没有排满以外,其他所有层均已排满。并且在构建完全二叉树的时候,新加入的节点在最后一层从左往右依次排列,直到排满为止。
![b9c62e35a18702978dcb8df12001f090.png](https://img-blog.csdnimg.cn/img_convert/b9c62e35a18702978dcb8df12001f090.png)
堆的构建
下面来说一说如何构建一个堆,如果数字越大的优先级越高,我们把这种堆称为大顶堆(max heap),数字越小,优先级越大的堆叫做小顶堆(min heap),这里以大顶堆为例,由于优先级越高的元素放置在越靠近根节点的位置,所以我们定义,所有父节点的值均大于等于其孩子节点的值,而孩子节点之间的大小我们不做要求,因此在大顶堆中根节点的值一定是最大值。例如下图中根节点 95 是最大值,它大于它的两个孩子节点 86 和 74,而节点 86 又大于节点 47 和 52。