如果我们给每个元素都分配一个数字来标记其优先级,不妨设较小的数字具有较高的优先级,这样我们就可以在一个集合中访问优先级最高的元素并对其进行查找和删除操作了。这样,我们就引入了优先级队列 这种数据结构。 优先级队列(priority queue) 是0个或多个元素的集合,每个元素都有一个优先权,对优先级队列执行的操作有(1)查找(2)插入一个新元素 (3)删除 一般情况下,查找操作用来搜索优先权最大的元素,删除操作用来删除该元素 。对于优先权相同的元素,可按先进先出次序处理或按任意优先权进行。
#ifndef _PRIORITYQUEUE_H_ #define _PRIORITYQUEUE_H_ #include "Array.h" template <class DataType> class PriorityQueue { public: PriorityQueue(); PriorityQueue(const Array<DataType>& arr); ~PriorityQueue(); void enqueue(const DataType& newElement); bool dequeue(DataType& remElement); bool isEmapty() const; void makeEmapty(); private: Array<DataType> elements; int heapsize; void heapify(int i); }; #endif
#include "PriorityQueue.h" template <class DataType> PriorityQueue<DataType>::PriorityQueue() :elements(2),heapsize(0) { } template <class DataType> PriorityQueue<DataType>::PriorityQueue(const Array<DataType>& arr) :elements(arr),heapsize(arr.length()) { for (int i=(heapsize-2)>>1;i>=0;i--) { heapify(i); } int trypower=2; for (;trypower<elements.length();trypower<<=1); if(trypower!=elements.length()) elements.ChangeSize(trypower); } template <class DataType> void PriorityQueue<DataType>::enqueue(const DataType& newElement) { if(heapsize==elements.length()) elements.ChangeSize(elements.length()<<1); int i=heapsize; for (;(i!=0)&&newElement>elements[(i-1)>>1];i=(i-1)>>1) { elements[i]=elements[(i-1)>>1]; } elements[i]=newElement; heapsize++; } template <class DataType> bool PriorityQueue<DataType>::dequeue(DataType& remElement) { if(!heapsize) return false; remElement=elements[0]; heapsize--; elements[0]=elements[heapsize]; heapify(0); int trysize=elements.length(); while ((heapsize<=trysize>>2)&&trysize>2) { trysize>>=1; } if(trysize<elements.length()) { try { elements.ChangeSize(trysize); } catch (...) {} } return true; } template <class DataType> bool PriorityQueue<DataType>::isEmapty() const { return !heapsize; } template <class DataType> void PriorityQueue<DataType>::makeEmapty() { heapsize=0; try { elements.ChangeSize(2); } catch(...) { } } template <class DataType> void PriorityQueue<DataType>::heapify(int i) { int leftChild,rightChild,largest; bool stop=false; DataType tmp=elements[i]; leftChild=(i<<1)+1; while (leftChild<heapsize && !stop) { rightChild=leftChild+1; largest=(rightChild==heapsize)?leftChild:((elements[leftChild]>elements[rightChild])?leftChild:rightChild); if (elements[largest]>tmp) { elements[i]=elements[largest]; i=largest; leftChild=(i<<1)+1; } else { stop=true; } } elements[i]=tmp; } template <class DataType> PriorityQueue<DataType>::~PriorityQueue() { makeEmapty(); }
#ifndef _ARRAY_H_ #define _ARRAY_H_ #include<string> using namespace std; template <class DataType> class Array { public: Array(const int size); inline DataType & operator [] (int index) { if (index < 0 || index > (capacity - 1)) { errorCode |= 8; //must have a value here return dud; } else { return elements[index]; } } void ChangeSize(int newSize); inline int length() const { return capacity; } string err() const; void Show() const; private: DataType *elements; int capacity; DataType dud; int errorCode; }; #endif
#include "Array.h" #include <string> using namespace std; // errorCode show the error // 0 No error. 2 Array error 4 ChangeSize error 8 operator [] error template <class DataType> Array<DataType>::Array(const int size) { if (size < 1) { capacity = 1; errorCode |= 2; } else { capacity = size; errorCode = 0; } elements = new DataType[size]; memset(elements, 0, sizeof(DataType) * size); } template <class DataType> void Array<DataType>::ChangeSize(int newSize) { if (newSize < 1) { errorCode |= 4; //the return value is void, and can use return directly return; } else { DataType *t; t = new DataType[newSize]; int longSize = newSize > capacity ? newSize : capacity; for (int i = 0; i < longSize; i++) t[i] = elements[i]; delete [] elements; elements = t; capacity = newSize; } } template <class DataType> string Array<DataType>::err() const { if ( !errorCode) return "No error.\n"; else if ( 2 & errorCode) return "Array error."; else if ( 4 & errorCode) return "ChangSize error.\n"; else return "operator error.\n"; } template <class DataType> void Array<DataType>::Show() const { for (int i = 0; i < capacity; i ++) cout<<elements[i]<<endl; }