把具有关键码{k0,k1,...,kn-1}的元素按完全二叉树的顺序存入到一个一维数组里,使它满足:

ki<=k2i+1, ki<=k2i+2.则称这个集合为最小堆.

它的任一节点的关键码都小于等于左右子树的关键码,位于堆顶的节点关键码是最小的.

template <class T>
class Heap
{
public:
    Heap(int n);
    Heap(T a[], int n);

    void insert(const T& x);
    bool removeMin(T& x);
private:
    void filterDown(int start, int end);
    void filterUp(int start);
protected:
    T* data;
    int size;
    int maxSize;
};

template <class T>
Heap<T>::Heap(int n)
{
    if (n <= 0)
    {
        cerr<<"Heap参数错误";
        return;
    }
    size = n;
    data = new T[size];
}

template<class T>
Heap<T>::Heap(T a[], int n)
{
    size = n;
    data = new T[size];

    memcpy(data, a, sizeof(T)):

    int pos = (size-2) / 2;
    while (pos >= 0)
    {
        filterDown(pos,size-1);
        pos--;
    }
}

template<class T>
void Heap<T>::filterDown(int start, int end)
{
    int i = start;
    int j = 2*i + 1; // j为i的左子节点
    T temp = data[i];

    while(j <= end)
    {
        if (j <= end && data[j] > data[j+1]) // 让j指向两个子节点中较小的
            j++;
        if (temp <= data[j]) // 不做调整
            break;
        else // 小的上移
        {
            data[i] = data[j];
            i = j;
            j = 2*j + 1;
        }
    }
    data[i] = temp;
}

template<class T>
void Heap<T>::filterUp(int start)
{
    int j = start;
    int i = (j-1) / 2;
    T temp = data[j];

    while (j > 0)
    {
        if(data[i] <= temp) // 不调整
            break;
        else // 调整
        {
            data[j] = data[i];
            j = i;
            i = (i-1) / 2;
        }
    }
    data[j] = temp;
}

template<class T>
void Heap<T>::insert(const T& x)
{
    enlarge();
    data[size] = x;
    filterUp(size);
    size++;
}

template<class T>
bool Heap<T>::removeMin(T& x)
{
    if (size == 0)
        return false;

    x = data[0];
    data[0] = data[size-1];
    size--;
    filterDowm(0,size-1);
    return true;
}

posted on 2012-09-25 21:52  赛欧拉  阅读(113)  评论(0)    收藏  举报