C语言实现二叉堆BuildHeap操作

优先队列(二叉堆)BuildHeap操作

BuildHeap(H)BuildHeap(H)操作把NN个关键字作为输入并把它们放入空堆中。显然,这可以使用NN个相继的InsertInsert操作来完成。由于每个InsertInsert将花费O(1)O(1)平均时间以及O(logN)O(log N)的最坏情形时间,因此该算法的总的运行时间则是O(N)O(N)的平均时间而不是O(NlogN)O(N log N)最坏情形时间。
一般的算法是将NN个关键字以任意顺序放入树中,保持 结构性 。此时,如果PercolateDown(i)PercolateDown(i)从节点ii下滤,那么执行下代码中的算法创建一颗具有堆序的树(heaporderedtreeheap-ordered-tree)。

二叉堆有两个性质:结构性质和堆序性质。

for(i = N / 2; i > 0; i--)
	PercolateDown(i);

定理

包含2b+112^{b+1}-1个节点高为bb理想二叉树(perfect binary tree)(也叫完全二叉树)的节点的高度的和为2b+11(b+1)2^{b+1}-1-(b+1)

代码

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);
    }
}

另一种线性时间实现方法

把每个元素当作是单节点左式堆,把所有这些堆放到一个队列中。之后,让两个堆出队,合并它们,再将合并结果入队,直到队列中只有一个堆为止。

该算法在最坏情形下为O(N)O(N)

此方法生成的堆更“左”。

不一定每天 code well 但要每天 live well
原文地址:https://www.cnblogs.com/geekfx/p/12423060.html