数据结构中的堆
堆(Heap)通常是一个可以看做一棵树的数组对象。在队列中,调度程序反复提取队列中第一个作业并运行,因为实际情况中某些事件较短的任务将等待很长时间才能结束,或者某些不算小,但具有重要性的作业同样应当具有优先权。堆即为解决此类问题设计的一种数据结构 ——-维基百科
堆又被成为优先级队列,尽管名为优先级队列,但是我们应该明确的是堆并不是队列。因为在队列中我们是按照进队列的顺序来取出元素。但是在堆中,我们不是按照元素进队列的顺序取元素,而是按照元素的优先级取出元素。从这里我们应该也要看出,堆的删除只能从根节点开始删除。因为堆的根节点是整个堆中优先级最高的。关于其具体解释,推荐阅读Vamei。
性质
堆的实现通过构造二叉堆,实际为二叉树的一种。
堆具有以下性质:
- 任意节点总是小于(或者大于)它的所有后裔,最小元(或者最大元)总是位于堆的根上,这成为堆序性。
- 堆总是一棵完全树,即除了最底层,其它层的节点均被元素填满,且最底层应尽可能地从左到右进行插入。
- 假设当前节点的索引为为x,那么它的父节点的索引为(x-1)/2,左子节点索引为2*x+1,右子节点索引为2*x+2。
从第一条性质我们可以看出,相对于二叉查找树来说,二叉堆是弱序树。
基本操作
操作 | 描述 | 时间复杂度 |
---|---|---|
build | 创建空堆 | O(n) |
insert | 向堆中插入一个新元素 | O( logn ) |
delete | 删除堆顶元素 | O( logn ) |
adjust | 使删除堆顶元素之后的堆再次调整为堆 |
我们应当明确上述各种操作的时间复杂度描述。
代码示例
代码来自倪升武的博客
package heap;
public class Heap
{
private Node[] heapArray;
private int maxSize;
private int currentSize;
public Heap(int mx)
{
maxSize = mx;
currentSize = 0;
heapArray = new Node[maxSize];
}
public boolean isEmpty()
{
return (currentSize == 0) ? true : false;
}
public boolean