堆排序算法是一个优秀的算法,但在实际应用中,快速排序的性能一般会由于堆排序。尽管如此,堆数据结构仍有许多应用。
优先队列是一种用来维护由一组元素构成的集合S的数据结构,每个元素都有相关的值,称为关键字。一个最大优先队列支持以下操作:
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可以在O(1)时间内实现maximum
heap-maximum(A){ return A[1];}
过程heap-extract-max实现extract-max
heap-extract-max(A){
if A.heap-size < 1
error "heap underflow"
max = A[1]
A[1] = A[A.heap-size]
A.heap-size = A.heap-size - 1
MAX-HEAPIFY(A,1)
return max
}
heap-extract-max的时间复杂度为O(lgn)。
heap-increase-key实现increase-key
-
当前元素不断与其父结点比较
-
如果当前元素的关键字较大,则与父结点交换
-
不断重复,直到当前元素关键字小于父结点时终止(维护最大堆性质)
heap-increase-key(A,i,key){
if key < A[i]
error 新关键比该关键字小
A[i] = key
while i > 1 and A[parent(i) < A[i] ]
exchange A[i] with A[parent(i)]
i = parent(i)
}
heap-increase-key过程在包含n个元素的堆上,时间复杂度为O(lgn)。
max-heap-insert实现insert操作
输入:要被插入到A中的新元素的关键字。
-
先增加一个关键字为-∞的叶结点扩展最大堆
-
调用heap-increase-key为新结点设置对应关键字
-
过程保持最大堆性质
max-heap-insert(A,key){
A.heap-size = A.heap-size + 1
A[A.heap-size] = -∞
heap-incerease-key(A, A.heap-size, key)
}
在包含n个元素的堆上,max-heap-insert时间复杂度为O(lgn)
通过以上几个操作实现,在一个包含n个元素的堆中,所有优先队列的操作都可以在O(lgn)时间内完成。