【C++】优先级队列的模拟实现

优先级队列是在堆的基础上进行的一个扩展,主要是运用大堆来实现优先级队列,让优先度高的出队列,最大优先队列可以选用大堆,最小优先队列可以选用小堆来实现。
下面以最大优先队列来讲解其原理。
最大优先队列一般包括将一个元素插入到集合S中、返回集合S中具有最大key的元素、返回并删除集合S中具有最大key的元素等。
堆的实现代码如下
下面给出实现代码:

#include <vector>
#include <assert.h>
using namespace std;
template<class T>
struct Less
{
    bool operator()(const T& left, const T& right)
    {
        return left < right;
    }
};

template<class T>
struct Greater
{
    bool operator()(const T& left, const T& right)
    {
        return left > right;
    }
};


template<class T, class Compare = Less<T>>
class Heap
{
public:
    Heap()
    {}

    Heap(const T array[], size_t size)
    {
        _heap.reserve(size);
        for (size_t i = 0; i < size; i++)
        {
            _heap.push_back(array[i]);
        }
        for (int j = (_heap.size() - 2) / 2; j >= 0; j--)
        {
            _AdjustDown(j);
        }
    }
    void Insert(const T& data)
    {
        assert(data);
        assert(!_heap.empty());
        _heap.push_back(data);
        _Adjustup(_heap.size() - 1);
    }
    void Remove()
    {
        assert(!_heap.empty());
        swap(_heap[0], _heap[size() - 1]);
        _heap.pop_back();
        _AdjustDown(0);
    }
    void Push(const T& x)  
    {  
        //插入到尾部,再从最后一个元素开始向上调整  
            _a.push_back(x);  
            AdjustUp(_a.size()-1);  
        }  
        void Pop()
    {
        //将堆顶与最后一个元素交换,再从堆顶下滑调整  
        assert(!_a.empty());
        swap(_a[0], _a[_a.size() - 1]);
        _a.pop_back();
        if (_a.size()>1)         //如果堆中的元素大于一个,再进行调整  
        {
            AdjustDown(0, _a.size());
        }
    }
    size_t Size()const
    {
        return _heap.size();
    }

    bool Empty()const
    {
        return _heap.empty();
    }

    const T& Top()const
    {
        assert(!_heap());
        return _heap[0];
    }

    void _AdjustDown(size_t parent)
    {
        assert(parent);
        assert(!_heap.empty());
        size_t child = parent * 2 - 1;
        while (parent < _heap.size())
        {
            Compare com;
            if (child + 1<_heap.size()&& com(_heap[child + 1], _heap[child]))
            {
                ++child;
            }
            if (child<_heap.size() && com(_heap[child], _heap[parent]))
            {
                swap(_heap[child], _heap[parent]);
                parent = child;
                child = parent * 2 + 1;
            }
            else
                break;
        }
    }
    void _AdjustUp(size_t child)
    {
        assert(!_heap.empty());
        while(child)
        {
            Compare com;
            size_t parent = (child - 1) / 2;
            if (com(_heap[child], _heap[parent]))
            {
                swap(_heap[child], _heap[parent]);
                child = parent;
            }
            else
                break;
        }
    }
private:
    vector<T> _heap;
};

template<class T, class Compare = Less<T>>
class PriorityQueue
{
public:
    PriorityQueue()
    {}
    PriorityQueue(T* a, size_t size)
        :_h(a, size)
    {
    }


    void Push(const T& data)
    {
        _hp.push(data);
    }
    void Pop()
    {
        _hp.pop();
    }
    const T& Top()const
    {
        _hp.Top();
    }
    size_t Size()const
    {
        return _heap.size();
    }

    bool Empty()const
    {
        return _hp.Empty();
    }

protected:
    Heap<T, Compare> _hp;
};
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值