数据结构-二叉树(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; }