看这篇文章需要对比较器有一定的了解,可以看我的这篇文章:
认识比较器_鱼跃鹰飞的博客-CSDN博客
堆的实际存储方式是数组,但是脑海中应该把他想象成一种树的结构
依次加入下标0-8的9个数(添加过程中会不断的和父节点大小进行比较,具体怎么比较根据当前堆是大根堆还是小根堆确定),对应的关系如下:
在这棵树中,对于某一个节点(数组中下标为i),他的父节点是: (i - 1)/2
他的左右子节点(如果存在,存在的判断条件是节点的坐标小于heapSize)分别是2*i + 1 和 2 * i + 2
堆分为大根堆和小根堆:
大根堆可以理解为整棵树以及树的所有子树都满足:当前树的最大节点是树的根节点
小根堆刚好相反,根是最小的节点,下面我们以大根堆为例来认知树的创建和调整的过程:
往堆中添加元素的过程:依次往堆中(实际上的数组和脑海中的树中)放入以下几个数:12,10,6, 8, 11
这个过程中添加11的时候有一步调整,因为11放在4位置违背了大根堆的原则(以10为根的这棵子树的根节点10不是这棵子树的最大节点)。
调整的过程:跟父节点比较直到父节点大于等于当前节点或者当前节点已经是根节点为止(只跟父节点比较,不管兄弟)。
堆的获取最大值并从堆中弹出的过程:
步骤:1.把根节点和堆中最后一个元素交换
2.当前根节点跟自己的左右孩子最大的比较,如果孩子比较大就和最大孩子交换。
3.一直调整到比左右孩子都大或者左右孩子不在堆中为止。