小根堆模板类

#include<iostream>
#include<Cstdio>
using namespace std;
template <class T>
class MinHeap{
private:
    T *heapArray;
    int CurrentSize;
    int MaxSize;
    void swap(int pos_x,int pos_y) //交换
    {
        T temp;
        temp=heapArray[pos_x];
        heapArray[pos_x]=heapArray[pos_y];
        heapArray[pos_y]=temp;
    }
    void BuildHeap();
public:
    MinHeap(const int n);
    bool isEmpty();
    bool isLeaf(int pos) const;
    int left(int pos) const;
    int right(int pos) const;
    int Parent(int pos) const;
    bool Remove(int pos,T &node);
    bool Remove(int pos);
    bool Insert(const T value);
    T& RemoveTop();
    void ShiftUp(int position);
    void ShiftDown(int left);
    void display()
    {
        cout << "MaxSize:" <<MaxSize<<endl;
        cout << "CurrentSize:" <<CurrentSize<<endl;
        for(int i=0;i<CurrentSize;i++)
        {
            cout << heapArray[i] << " ";
        }
        cout <<endl;
    }

};
template <class T>
MinHeap<T>::MinHeap(const int n)
{
    if(n<0)return;
    MaxSize=n;
    CurrentSize=0;
    heapArray=new T[MaxSize];
    BuildHeap();
}
template <class T>
bool MinHeap<T>::isLeaf(int pos) const{ //判断是否为叶子节点
    return (pos>=CurrentSize/2)&&(pos<CurrentSize);
}
template <class T>
void MinHeap<T>::BuildHeap(){ //建堆
    for(int i=CurrentSize/2-1;i>=0;i--)
    {
        ShiftDown(i);
    }
}
template <class T>
int MinHeap<T>::left(int pos) const
{
    return 2*pos+1;
}
template <class T>
int MinHeap<T>::right(int pos) const
{
    return 2*pos+2;
}
template <class T>
int MinHeap<T>::Parent(int pos) const
{
    return ((pos-1)/2);
}
template <class T>
bool MinHeap<T>::Insert(const T value) //新结点插入数组尾部并做一次上浮操作
{
    if(CurrentSize==MaxSize)
        return false;
    heapArray[CurrentSize]=value;
    ShiftUp(CurrentSize);
    CurrentSize++;
    return true;
}
template <class T>
T& MinHeap<T>::RemoveTop() //弹出最小值
{
    if(CurrentSize==0)
    {
        cout << "Heap is empty" <<endl;
        return heapArray[CurrentSize-1];
    }
    else
    {
        swap(0,--CurrentSize);
        if(CurrentSize>1)
            ShiftDown(0);
        return heapArray[CurrentSize];
    }
}
template <class T>
bool MinHeap<T>::Remove(int pos,T &node) //删除下标为pos的结点,将最后一个元素值与之替换
{
    if((pos<0)||(pos>=CurrentSize))return false;
    node=heapArray[pos];
    heapArray[pos]=heapArray[--CurrentSize];
    if(heapArray[Parent(pos)]>heapArray[pos]) //根据替换后的删除节点选择上浮或下沉
        ShiftUp(pos);
    else ShiftDown(pos);
    return true;
}
template <class T>
void MinHeap<T>::ShiftUp(int pos) //上浮
{
    int temppos=pos; //初始化为上浮结点位置
    T temp=heapArray[temppos]; //上浮结点值
    while((temppos>0)&&(heapArray[Parent(temppos)]>temp)) //当前结点的父节点大于上浮结点
    {
        heapArray[temppos]=heapArray[Parent(temppos)];
        temppos=Parent(temppos);
    }
    heapArray[temppos]=temp;
}
template <class T>
void MinHeap<T>::ShiftDown(int l) //下沉
{
    //从左子树下沉
    int i=l;
    int j=left(i); //当前结点初始化为左子树
    T temp=heapArray[i];
    while(j<CurrentSize)
    {
        if((j<CurrentSize-1)&&(heapArray[j]>heapArray[j+1]))
        {
            //存在右子树且右结点小于左结点,指向右结点
            j++;
        }
        if(temp>heapArray[j]) //下沉节点值大于当前节点
        {
            heapArray[i]=heapArray[j]; //下沉
            i=j;
            j=left(j);
        }
        else break;
    }
    heapArray[i]=temp;
}

int main()
{
    MinHeap<int> a(1000);
    int n;
    int s,p;
    while(cin>>n)
    {
        for(int i=0;i<n;i++)
        {
            cin>>s;
            a.Insert(s);
        }
        a.display();
        cin>>s;
        a.Remove(s,p);
        cout << "remove No." << s <<" value is "<<p<<endl;
        a.display();
        cout << "top:" <<a.RemoveTop() <<" removed" <<endl;
        a.display();

    }
}

猜你喜欢

转载自www.cnblogs.com/LowBee/p/9024928.html