二叉堆
二叉堆是一颗完全二叉树,该树中的某个节点的值总是不大于(不小于)其左右子节点的值,包括最小堆和最大堆。可以通过下图理解,为什么会使用数组来保存呢?因为利用完全二叉树的性质,我们可以通过数组来表示完全二叉树(数组下标与完全二叉树节点存在映射关系,比如父节点可以通过Math.floor((index-1)/2)来获取、左子节点可以通过2index+1来获取、右子节点可以通过2index+2来获取,从而简化了实现及开销,避免使用额外的指针来实现树结构。
最小(大)堆性质
树根节点的值是所有堆节点值中最小(大)值。
树中每个节点的子树也都是最小(大)堆。
最小(大)堆作用
最小(大)堆能保证堆顶元素为最小,而如果使用数组无法达到该效果。数组如果要访问最小值则需要遍历查找最小值,时间复杂度至少O(n)。而最小堆访问最小值时间复杂度为O(1),当然天底下没有免费的午餐,我们需要做额外的工作去维护最小(大)堆的结构,这也是需要复杂度花销的。
当然这也是最小(大)堆的优势,通过动态维护使得最小值的获取代价很小,实际上维护的时间复杂度为O(logN)。而数组则无法做到如此,如果数组想要维护顺序性则需要的复杂度至少为O(N)。这样来看最小(大)堆的优势就凸现出来了。
插入操作
为避免冗长累赘,我们这里只挑最小堆作为例子进行说明,最大堆的情况与最大堆相