5.1 堆 —— 堆的定义与操作

#include <stdio.h>
#include <stdlib.h>

typedef struct HeapStruct *MaxHeap;
struct HeapStruct{
    ElementsType *Elements;
    int ESize;
    int Capacity;
};

bool isFull(MaxHeap H)
{
    return (H->ESize == H->Capacity);
}

bool isEmpty(MaxHeap H){
    return (H->ESize == 0);
}

MaxHeap Create(int MaxSize)
{
    MaxHeap H = malloc(sizeof(struct HeapStruct));
    H->Elements = malloc((MaxSize + 1) * sizeof(ElementsType));
    H->ESize = 0;
    H->Capacity = MaxSize;
    H->Elements[0] = MaxData;
    return H;
}

void Insert(MaxHeap H, ElementsType item)
{  //T(N) = O(logN)
    int i;
    if(isFull(H)){
        printf("最大堆已满\n");
        return;
    }
    i = ++H->ESize;
    for( ; H->Elements[i / 2] < item; i /= 2)
        H->Elements[i] = H->Elements[i / 2];
    H->Elements[i] = item;
}

ElementsType DeleteMax(MaxHeap H)
{
    int Parent, Child;  //位置标记
    ElementsType MaxItem, temp;
    if(isEmpty(H)){
        printf("最大堆已空\n");
        return;
    }
    MaxItem = H->Elements[1];
    temp = H->Elements[H->ESize];
    H->ESize--;
    for(Parent = 1; Parent * 2 <= H->ESize; Parent = Child){
        //只要当前位置(Parent所指向)还有儿子结点,就继续循环判断
        Child = Parent * 2;
        if(Child != H->ESize && (H->Elements[Child] < H->Elements[Child + 1]))
            Child++;
        if(temp >= H->Elements[Child])
            break;
        else
            H->Elements[Parent] = H->Elements[Child];
    }
    H->Elements[Parent] = temp;
    return MaxItem;
}

void PrecDown(MaxHeap H, int p)
{
    int Parent, Child;
    ElementsType X;
    X = H->Elements[p];
    for(Parent = p; Parent * 2 <= H->ESize; Parent = Child){
        Child = Parent * 2;
        if(Child != H->ESize && (H->Elements[Child] < H->Elements[Child + 1]))
            Child++;
        if(X >= H->Elements[Child])
            break;
        else
            H->Elements[Parent] = H->Elements[Child];
    }
    H->Elements[Parent] = X;
}

void BuildHeap(MaxHeap H)
{  //假设所有H->ESize个元素已经存在H->Elements[]中
    int i;
    for(i = H->ESize / 2; i > 0; i++)  //从最后一个结点的父节点开始,到根节点1
        PrecDown(H, i);
}

猜你喜欢

转载自www.cnblogs.com/biankun/p/8975221.html