优先队列(二叉堆)BuildHeap操作
操作把个关键字作为输入并把它们放入空堆中。显然,这可以使用个相继的操作来完成。由于每个将花费平均时间以及的最坏情形时间,因此该算法的总的运行时间则是的平均时间而不是最坏情形时间。
一般的算法是将个关键字以任意顺序放入树中,保持 结构性 。此时,如果从节点下滤,那么执行下代码中的算法创建一颗具有堆序的树()。
二叉堆有两个性质:结构性质和堆序性质。
for(i = N / 2; i > 0; i--)
PercolateDown(i);
定理
包含个节点高为的理想二叉树(perfect binary tree)(也叫完全二叉树)的节点的高度的和为 。
代码
PriorityQueue BuildHeap(ElementType *Elements, int N)
{
int i;
PriorityQueue H;
H = Initialize(N);
for (i = 1; i <= N; i++)
H->Elements[i] = Elements[i - 1];
H->Size = N;
for (i = N / 2; i > 0; i--)
PercolateDown(i, H);
return H;
}
void PercolateDown(int i, PriorityQueue H)
{
int MinSon, Min;
ElementType Tmp;
if (i <= H->Size / 2)
{
MinSon = i * 2 + 1 <= H->Size && H->Elements[i * 2] > H->Elements[i * 2 + 1] ? i * 2 + 1 : i * 2;
Min = H->Elements[i] < H->Elements[MinSon] ? i : MinSon;
Tmp = H->Elements[i];
H->Elements[i] = H->Elements[MinSon];
H->Elements[MinSon] = Tmp;
PercolateDown(MinSon, H);
}
}
另一种线性时间实现方法
把每个元素当作是单节点左式堆,把所有这些堆放到一个队列中。之后,让两个堆出队,合并它们,再将合并结果入队,直到队列中只有一个堆为止。
该算法在最坏情形下为。
此方法生成的堆更“左”。