heap
heap(堆),并不属于STL容器组件,作为priority_queue(优先队列)的底层容器。而heap的底层容器是vector。
priority_queue的特点就是推入多个元素,当取出时,取出的是priority_queue里面优先级最高的那个元素,元素的优先级可以自定义也可以默认按照大小顺序。
binary max heap 正是具有这样的特性,适合做为 priority queue 的底层机制。
堆和二叉搜索树的区别
有一个问题:二叉搜索树也可以满足priority_queue的要求,为什么用堆而不用二叉搜索树。
所以我们写看看堆和二叉搜索树的区别:
节点的顺序:在二叉搜索树中,左子节点必须比父节点小,右子节点必须必比父节点大。但是在堆中并非如此。在最大堆中两个子节点都必须比父节点小,而在最小堆中,它们都必须比父节点大。
内存占用。普通树占用的内存空间比它们存储的数据要多。你必须为节点对象以及左/右子节点指针分配额为是我内存。堆仅仅使用一个数据来存储数组,且不使用指针。
平衡。二叉搜索树必须是“平衡”的情况下,其大部分操作的复杂度才能达到O(log n)。你可以按任意顺序位置插入/删除数据,或者使用 AVL 树或者红黑树,但是在堆中实际上不需要整棵树都是有序的。我们只需要满足对属性即可,所以在堆中平衡不是问题。因为堆中数据的组织方式可以保证O(log n) 的性能。
搜索。在二叉树中搜索会很快,但是在堆中搜索会很慢。在堆中搜索不是第一优先级,因为使用堆的目的是将最大(或者最小)的节点放在最前面,从而快速的进行相关插入、删除操作。
所以我们现在可以总结一下了,使用堆的优点:
1.内存占用小
2.不需要平衡,只需要保证子树小于当前节点。
3.因为优先队列不需要搜索,只找最大或最小值,所以时间上也不会慢。
heap的push操作
在将push操作之前我们明确三个前提:
1.heap使用数组存储数据。
某节点下标为x,它的左子节点下标则为2x,它的右子节点下标则为2x+1。利用了这一特性就可以将数据存在数组中。
2.heap是一个完全二叉树
3.堆有大根堆和小根堆(也有人称为大顶堆小顶堆,一样的),下文所说的heap都是大根堆。
push操作
1.新push进来的元素会存放在数组的最后面,也就是heap的最底层的[最右边的节点]。&#x