堆一个很常见的应用:作为高效的优先级队列。如堆一样,队列也有两种:最大优先级队列和最小优先级队列。优先级队列是一种用来维护由一组元素构成的集合S的数据结构,这一组元素中的每一个都有一个关键字key。一个最大优先级队列支持以下操作:
- INSERT(S, x):把元素x插入集合S。
- MAXIMUM(S):返回S中具有最大关键字的元素。
- EXTRACT-MAX(S):去掉并返回S中的具有最大关键字的元素。
- INCREASE-KEY(S, x, k):将元素x的关键字的值增加到k,这里k值不能小于x的原关键字的值。
最大优先级队列的一个应用是在一台分时计算机上进行作业调度。这种队列对要执行的各作业及他们之间的相对优先关系加以记录。当一个作业做完或被中断时,用EXTRACT-MAX操作从所有等待的作业中,选择出具有最高优先级的作业。在任何时候,一个新作业都可以用INSERT加入到队列中去。
一、取出最大元素
程序HEAP-MAXIMUM实现MAXIMUM操作
HEAP-MAXIMUM(A)
return A[1]
二、去除最大元素
HEAP-EXTRACT-MAX(A)
if heap-size[A] < 1
then error "heap underflow"
max <- A[1]
A[1] <- A[heap-size[A]]
heap-size[A] <- heap-size[A] - 1
MAX-HEAPIFY(A, 1)
return max
三、增加元素
关键字需要增加的元素由对应数组的小标i来标识。在从本结点往根结点移动的路径上,为新增大的关键字寻找合适的位置。在移动的过程中,此元素不断地与其父母相比,如果此元素的关键字较大,则交货它们的关键字且继续移动。当元素的关键字小于其父母时,此时最大堆性质成立,因此程序终止。
HEAP-INCREASE-KEY(A, i, key)
if key < A[i]
then error "new key is smaller than current key"
A[i] <- key
while i > 1 and A[PARENT(i)] < A[i]
do exchange A[i] <->A[PARENT(i)]
i <- PARENT(i)
下面的MAX-HEAP-INSERT实现了INSERT操作。它的输入是要插入到最大堆A中的新元素的关键字。这个程序首先加入一个关键字值为负无穷大的叶节点来扩展最大堆,然后调用HEAP-INCREASE-KEY来设置新结点的关键字的正确值,并保持最大堆性质。
MAX-HEAP-INSERT(A, key)
heap-size[A] <- heap-size[A] + 1
A[heap-size[A]] <- -max(int)
HEAP-INCREASE-KEY(A, heap-size[A], key)
在包含n个元素的堆上,MAX-HEAP-INSERT的运行时间为O(lgn)。
课后题:在堆排序的BULID-MAX-HEAP过程也可以通过反复调用MAX-HEAP-INSERT,将各元素插入堆中实现。
BUILD-MAX-HEAP‘(A)
heap-size[A] <- 1
for i <- 2 to length[A]
do MAX-HEAP-INSERT(A, A[i])