
關於地理學的堆積,請見堆積作用。關於名稱相近的資料結構,請見
堆栈(
Stack)。
堆(Heap)是计算机科学中的一種特別的完全二叉树。若是滿足以下特性,即可稱為堆積:「給定堆積中任意節點P和C,若P是C的父節點,那麼P的值會小於等於(或大於等於)C的值」。若父節點的值恆小於等於子節點的值,此堆積稱為最小堆積(min heap);反之,若父節點的值恆大於等於子節點的值,此堆積稱為最大堆積(max heap)。在堆積中把根節點(root node)稱為堆積頂(top),而底層最靠右的節點稱為堆積底(bottom)。
堆積始於J. W. J. Williams在1964年發表的堆積排序(heap sort),當時他提出了二元堆積樹作為此演算法的資料結構。
性质
堆的实现通过构造二叉堆(binary heap),实为二叉树的一种;由于其应用的普遍性,当不加限定时,均指该数据结构的这种实现。这种数据结构具有以下性质。
- 任意节点小于(或大于)它的所有后裔,最小元(或最大元)在堆的根上(堆序性)。
- 堆总是一棵完全树。即除了最底层,其他层的节点都被元素填满,且最底层尽可能地从左到右填入。
将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。
堆有許多種進階類型包含了適合製作雙端佇列的最大—最小堆積及製作優先權佇列的斐波那契堆積等。
支持的基本操作
| 操作 |
描述 |
时间复杂度
|
| build |
採用羅伯特·弗洛伊德提出的較快方式建立堆 |
|
| insert |
向堆中插入一个新元素 |
|
| update |
将新元素提升使其符合堆的性质 |
|
| get |
获取当前堆顶元素的值 |
|
| delete |
删除堆顶元素 |
|
| heapify |
使删除堆顶元素的堆再次成为堆 |
|
某些堆实现还支持其他的一些操作,如斐波那契堆支持检查一个堆中是否存在某个元素。
示例代码
为将元素X插入堆中,找到空闲位置,建立一个空穴,若满足堆序性(英文:heap order),则插入完成;否则将父节点元素装入空穴,删除该父节点元素,完成空穴上移。直至满足堆序性。这种策略叫做上滤(percolate up)。[1]
void Insert( ElementType X, PriorityQueue H ) {
int i;
if (IsFull(H)) {
printf("Queue is full.\n");
return;
}
for (i = ++H->Size; H->Element[i / 2] > X; i /= 2)
H->Elements[i] = H->Elements[i / 2];
H->Elements[i] = X;
}
以上是插入到一个二叉堆的过程。
DeleteMin,删除最小元,即二叉树的根或父节点。删除该节点元素后,队列最后一个元素必须移动到堆得某个位置,使得堆仍然满足堆序性质。这种向下替换元素的过程叫作下滤。
ElementType DeleteMin(PriorityQueue H) {
int i, Child;
ElementType MinElement, LastElement;
if (IsEmpty(H)) {
printf("Queue is empty.\n");
return H->Elements[0];
}
MinElement = H->Elements[1];
LastElement = H->Elements[H->Size--];
for (i = 1; i * 2 <= H->Size; i = Child) {
// Find smaller child.
Child = i * 2;
if (Child != H->Size && H->Elements[Child + 1]
< H->Elements[Child])
Child++;
// Percolate one level.
if (LastElement > H->Elements[Child])
H->Elements[i] = H->Elements[Child];
else
break;
}
H->Elements[i] = LastElement;
return MinElement;
}
应用
堆排序
堆(通常是二叉堆)常用于排序。这种算法称作堆排序。
事件模拟
主要运用堆的排序以选择优先。
優先權佇列
在队列中,调度程序反复提取队列中第一个作业并运行,因为实际情况中某些时间较短的任务将等待很长时间才能结束,或者某些不短小,但具有重要性的作业,同样应当具有优先权。堆即为解决此类问题设计的最佳数据结构。[1]
戴克斯特拉演算法
在戴克斯特拉演算法中使用斐波那契堆積或二元堆可使得佇列的操作更為快速。
参考
- ^ 1.0 1.1 《数据结构与算法分析》Mark Allen Weiss(美)第六章,优先队列(堆)。
参见
- 二叉堆
- 二项式堆
- 最小-最大堆
- 斐波纳契堆
- 数据结构
|
|---|
| 二叉树 |
- 二元搜尋樹
- 笛卡尔树
- MVP树
- Top tree
- T树
- 线索二叉树
|
|---|
| 自平衡二叉查找树 |
- AA树
- AVL树
- 左倾红黑树
- 红黑树
- 替罪羊树
- 伸展树
- 树堆
- 加权平衡树
|
|---|
| B树 |
- B+树
- B*树
- Bx树
- UB树
- 2-3树
- 2-3-4树
- (a,b)-树
- 跳舞樹
- H树
|
|---|
| 堆 |
- 二叉堆
- 二项堆
- 斐波那契堆
- 左偏树
- 配对堆
- 斜堆
- 范恩德蟒蛇樹
|
|---|
| Trie |
- 后缀树
- 基数树
- 三叉查找树
- X-快速前缀树
- Y-快速前缀树
- AC自动机
|
|---|
| 二叉空间分割(BSP)树 | |
|---|
| 非二叉树 | |
|---|
| 空间数据分割树 |
- R树
- R*树
- R+树
- X树
- M树
- 線段樹 (儲存區間)
- 线段树 (区间查询)
- 希尔伯特R树
- 优先R树
|
|---|
| 其他树 |
- 散列日历
- 散列树
- 手指樹
- 顺序统计树
- 度量樹
- 覆蓋樹
- BK树
- 二重連鎖樹
- iDistance
- Link-cut tree
- Log-structured merge-tree
- 树状数组
- 哈希树
|
|---|