✍ dations ◷ 2024-12-22 22:56:51 #数据结构,树结构,堆

堆(英语:Heap)是计算机科学中的一种特别的树状数据结构。若是满足以下特性,即可称为堆:“给定堆中任意节点P和C,若P是C的母节点,那么P的值会小于等于(或大于等于)C的值”。若母节点的值恒小于等于子节点的值,此堆称为最小堆(min heap);反之,若母节点的值恒大于等于子节点的值,此堆称为最大堆(max heap)。在堆中最顶端的那一个节点,称作根节点(root node),根节点本身没有母节点(parent node)。

堆始于J. W. J. Williams(英语:J. W. J. Williams)在1964年发表的堆排序(heap sort),当时他提出了二叉堆树作为此算法的数据结构。堆在戴克斯特拉算法(英语:Dijkstra's algorithm)中亦为重要的关键。

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

堆的实现通过构造二叉堆(binary heap),实为二叉树的一种;由于其应用的普遍性,当不加限定时,均指该数据结构的这种实现。这种数据结构具有以下性质。

将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。常见的堆有二叉堆、斐波那契堆等。

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

为将元素X插入堆中,找到空闲位置,创建一个空穴,若满足堆序性(英文:heap order),则插入完成;否则将父节点元素装入空穴,删除该父节点元素,完成空穴上移。直至满足堆序性。这种策略叫做上滤(percolate up)。

 1 void Insert( ElementType X, PriorityQueue H ) { 2     int i; 3     if (IsFull(H)) { 4         printf("Queue is full.\n"); 5         return; 6     } 7     for (i = ++H->Size; H->Element > X; i /= 2) 8         H->Elements = H->Elements; 9     H->Elements = X;10 }

以上是插入到一个二叉堆的过程。

DeleteMin,删除最小元,即二叉树的根或父节点。删除该节点元素后,队列最后一个元素必须移动到堆得某个位置,使得堆仍然满足堆序性质。这种向下替换元素的过程叫作下滤。

 1 ElementType DeleteMin(PriorityQueue H) { 2     int i, Child; 3     ElementType MinElement, LastElement; 4     if (IsEmpty(H)) { 5         printf("Queue is empty.\n"); 6         return H->Elements; 7     } 8     MinElement = H->Elements; 9     LastElement = H->Elements;10     for (i = 1; i * 2 <= H->Size; i = Child) {11         // Find smaller child.12         Child = i * 2;13         if (Child != H->Size && H->Elements14                 <  H->Elements)15             Child++;16         // Percolate one level.17         if (LastElement > H->Elements)18             H->Elements = H->Elements;19         else20             break;21     }22     H->Elements = LastElement;23     return MinElement;24 }

应用

堆排序

堆(通常是二叉堆)常用于排序。这种算法称作堆排序。

主要运用堆的排序以选择优先。

相关