/************************************************ * *author:周翔 *e-mail:604487178@qq.com *blog:http://blog.csdn.net/zhx6044 * * *************************************************/ #ifndef PRIORITYQUEUE_HPP #define PRIORITYQUEUE_HPP #include <iostream> template <typename T> /** * @brief The PriorityQueue class 使用徹底二叉樹的順序實現實現(二叉堆)的優先級隊列,這個爲最大化堆,大值優先,註釋掉的爲最小化堆 */ class PriorityQueue { template <typename N> friend std::ostream& operator << (std::ostream &os, const PriorityQueue<N> &t) { for (int i = 1;i <= t.nowSize;++i) { os << t.d[i] << " "; } return os; } public: PriorityQueue(int _s = DEFAULT); PriorityQueue(const T arr[], int n); ~PriorityQueue(); void enQueue(const T &t); T deQueue(); T head() const; bool isEmpty() const; private: enum {DEFAULT = 20}; int cap; /** * @brief nowSize 當前節點的個數,也是徹底二叉樹最下層最右節點在數組中的下標 */ int nowSize; /** * @brief d 第一個也就是下標爲0不存數據,從一開始,這樣方便了2*I,2*i+1,和2/i向下取整的計算,也就是左右節點和父節點的計算 */ T *d; /** * @brief expand 擴大空間 */ void expand(); /** * @brief build 經過傳入的數組創建堆 */ void build(); /** * @brief help 輔助函數,實現一個非葉子節點根的子樹的向下規格 * @param i */ void help(int i); }; template <typename T> PriorityQueue<T>::PriorityQueue(int _s):cap(_s),nowSize(0) { d = new T[cap]; } template <typename T> PriorityQueue<T>::PriorityQueue(const T arr[], int n):cap(n+10),nowSize(n) { d = new T[cap]; for (int i = 1;i <= nowSize;++i) { d[i] = arr[i-1]; } build(); } template <typename T> PriorityQueue<T>::~PriorityQueue() { delete[] d; } template <typename T> T PriorityQueue<T>::head() const { return d[1]; } template <typename T> bool PriorityQueue<T>::isEmpty() const { return nowSize == 0; } template <typename T> void PriorityQueue<T>::expand() { T *t = d; d = new T[cap*2]; for (int i = 1;i <= nowSize;++i) { d[i] = t[i]; } cap *= cap; delete[] t; } template <typename T> void PriorityQueue<T>::build() { for (int i = nowSize / 2;i > 0;--i) { help(i); } } template <typename T> void PriorityQueue<T>::help(int i) { T t = d[i]; int c; while (i * 2 < nowSize) {//存在子節點 c = (d[2 * i] > d[2 * i + 1]) ? (2 * i) : (2 * i + 1); if (d[c] > t) { //c = (d[2 * i] < d[2 * i + 1]) ? (2 * i) : (2 * i + 1); //if (d[c] < t) { d[i] = d[c]; i = c; } else { break; } } d[i] = t; } template <typename T> T PriorityQueue<T>::deQueue() { T tem = d[1]; //將最下層最右節點最爲新的根,在重新規格一次 d[1] = d[nowSize--]; help(1);//從1開始 return tem; } template <typename T> void PriorityQueue<T>::enQueue(const T &t) { if (nowSize == cap - 1) expand(); int i = ++nowSize; for (;i > 1 && t > d[i/2];i /= 2) {//從這個節點向上比較 // for (;i > 1 && t < d[i/2];i /= 2) {//從這個節點向上比較 d[i] = d[i/2]; } d[i] = t; } #endif // PRIORITYQUEUE_HPP
#include "priorityqueue.hpp" int main() { int arr[] = {40,20,60,15,30,25,10,35,45,50,55}; PriorityQueue<int> pQueue(arr,11); // pQueue.deQueue(); std::cout << pQueue << std::endl; }
去掉註釋ios
修護bug一個數組
template <typename T> void PriorityQueue<T>::help(int i) { T t = d[i]; int c; //對付最下層最右節點爲左節點的問題 if (i * 2 == nowSize) { if (d[i*2] < t) { d[i] = d[i*2]; i = 2 * i; } } while (i * 2 < nowSize) {//存在子節點 // c = (d[2 * i] > d[2 * i + 1]) ? (2 * i) : (2 * i + 1); // if (d[c] > t) { c = (d[2 * i] < d[2 * i + 1]) ? (2 * i) : (2 * i + 1); if (d[c] < t) { d[i] = d[c]; i = c; } else { break; } } d[i] = t; }
測試代碼:函數
#include "priorityqueue.hpp" int main() { int arr[] = {40,20,60,15,50,25,10,35,45,30}; PriorityQueue<int> pQueue(arr,10); // pQueue.deQueue(); std::cout << pQueue << std::endl; }
小弟精力有限,bug你們發現了,請通知聲哈
測試