优先级队列

/************************************************
*
*author:周翔
*e-mail:[email protected]
*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;
}

优先级队列


去掉注释

优先级队列


修护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大家发现了,请通知声哈吐舌头



你可能感兴趣的:(优先级队列)