堆積

堆（）是计算机科学中的一種特別的完全二叉树。若是滿足以下特性，即可稱為堆積：「給定堆積中任意節點P和C，若P是C的父節點，那麼P的值會小於等於（或大於等於）C的值」。若父節點的值恆小於等於子節點的值，此堆積稱為最小堆積（）；反之，若父節點的值恆大於等於子節點的值，此堆積稱為最大堆積（）。在堆積中把根節點（）稱為堆積頂（top），而底層最靠右的節點稱為堆積底（bottom）。

堆積始於在1964年發表的堆積排序（），當時他提出了二元堆積樹作為此演算法的資料結構。

性质
堆的实现通过构造二叉堆（binary heap），实为二叉树的一种；由于其应用的普遍性，当不加限定时，均指该数据结构的这种实现。这种数据结构具有以下性质。
 任意节点小于（或大于）它的所有后裔，最小元（或最大元）在堆的根上（堆序性）。
 堆总是一棵完全树。即除了最底层，其他层的节点都被元素填满，且最底层尽可能地从左到右填入。
将根节点最大的堆叫做最大堆或大根堆，根节点最小的堆叫做最小堆或小根堆。

堆有許多種進階類型包含了適合製作雙端佇列的最大—最小堆積及製作優先權佇列的斐波那契堆積等。

 支持的基本操作 

 操作  描述  时间复杂度 build  採用羅伯特·弗洛伊德提出的較快方式建立堆   insert  向堆中插入一个新元素   update  将新元素提升使其符合堆的性质   get  获取当前堆顶元素的值   delete  删除堆顶元素   heapify  使删除堆顶元素的堆再次成为堆  

某些堆实现还支持其他的一些操作，如斐波那契堆支持检查一个堆中是否存在某个元素。

示例代码
为将元素X插入堆中，找到空闲位置，建立一个空穴，若满足堆序性（英文：heap order），则插入完成；否则将父节点元素装入空穴，删除该父节点元素，完成空穴上移。直至满足堆序性。这种策略叫做上滤（percolate up）。《数据结构与算法分析》Mark Allen Weiss（美）第六章，优先队列（堆）。
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;
}

 应用 
 堆排序 

堆（通常是二叉堆）常用于排序。这种算法称作堆排序。
 事件模拟 
主要运用堆的排序以选择优先。

 優先權佇列 
在队列中，调度程序反复提取队列中第一个作业并运行，因为实际情况中某些时间较短的任务将等待很长时间才能结束，或者某些不短小，但具有重要性的作业，同样应当具有优先权。堆即为解决此类问题设计的最佳数据结构。

 戴克斯特拉演算法 
在戴克斯特拉演算法中使用斐波那契堆積或二元堆可使得佇列的操作更為快速。

参考

 参见 
 二叉堆
 二项式堆
 最小-最大堆
 斐波纳契堆
 数据结构

D
Category:树结构