数据结构-二叉树(5)利用数组实现堆

#define DefaultSize 10;

template <class E>   //堆中存储的是一个记录的集合,并根据每个记录的关键码以最小堆序排序,在使用堆操作之前需要定义记录的结构类型,用E表示
class MinHeap:public PQueue<E>{
    //最小堆类继承了最小优先级队列
public:
    MinHeap(int sz=DefaultSize);
    MinHeap(E arr[],int n);
    ~MinHeap(){delete []heap};
    bool Insert(const E& x);
    bool RemoveMin(E& x);
    bool IsEmpty()const{return currentSize==0;}
    bool IsFull()const{return currentSize==maxHeapSize;}
    void MakeEmpty(){currentSize=0;}
private:
    E *heap;
    int currentSize;
    int maxHeapSize;
    void siftDown(int start,int m);
    void siftUp(int start);
}

template <class T>
MinHeap<E>::MinHeap(int sz=DefaultSize){
    maxHeapSize=(DefaultSize<sz)?sz:DefaultSize;
    heap=new E[maxHeapSize];
    if(heap==NULL){
        cerr<<"堆存储分配失败!"<<endl;
        exit(1);
    }
    currentSize=0;
}

template <class T>
MinHeap<E>::MinHeap(E arr[],int n){   //复制构造函数,数组调整成堆
    maxHeapSize=(DefaultSize<n)?n:DefaultSize;  //取n和DefaultSize中比较大的一个作为最小堆的大小
    heap=new E[maxHeapSize];
    if(heap==NULL){
        cerr<<"堆分配存储失败!"<<endl;
        exit(1);
    }
    for(int i=0;i<n;i++) heap[i]=arr[i];
    currentSize=n;
    int currentPos=(currentSize-2)/2;     //找最初调整位置:最后分支结点(最后一个结点的父结点)
    while(currentPos>=0){                  //自底向上逐步扩大成堆
        siftDown(currentPos,currentSize-1);   //局部自上向下下滑调整
        currentPos--;        //再向前换一个分支结点
    }
}

template <class T>
void MinHeap<E>::siftDown(int start,int m){
    //私有函数,从结点start开始到m为止,自上而下比较,如果子女的值小于父结点的值,则关键码小的上浮,继续向下层比较,这样将一个集合局部调整为最小堆
    int i=start,j=2*i+1;   //j指向i的左子女
    E temp=heap[i];
    while(j<=m){
        if(j<m && heap[j]>heap[j+1]) j++;   //让j指向两子女中的小者
        if(temp<=heap[j]) break;
        else{
            heap[i]=heap[j];
            i=j;
            j=2*j+1;
        }
    }
    heap[i]=temp;
}

template <class E>
void MinHeap<E>::siftUp(int start){
    //私有函数:从结点start开始到结点0为止,自下而上比较,如果子女的值小于父结点的值则相互交换,这样将集合重新调整为最小堆,关键码比较符<=在E的类型中定义
    int j=start,i=(j-1)/2;   //j指向i的父结点
    E temp=heap[j];
    while(j>0){
        if(heap[i]<=temp)break;
        else{
            heap[j]=heap[i];
            j=i;
            i=(i-1)/2;
        }
    }
    heap[j]=temp;
}

template <class E>
bool MinHeap<E>::Insert(const E& x){
    if(currentSize==maxHeapSize){
        cerr<<"Heap Full"<<endl;
        return false;
    }
    heap[currentSize]=x;
    siftUp(currentSize);    //向上调整
    currentSize++;
    return true;
}

template <class E>
bool MinHeap<E>::RemoveMin(E &x){
    if(!currentSize){
        cout<<"Heap empty"<<endl;
        return false;
    }
    x=heap[0];
    heap[0]=heap[currentSize-1];
    currentSize--;
    siftDown(0,currentSize-1);
    return true;
}

 

posted @ 2018-08-09 14:23  扬羽流风  阅读(866)  评论(0编辑  收藏  举报