优先级队列---使用堆

来源:互联网 发布:感情 知乎 编辑:程序博客网 时间:2024/06/01 08:01
   优先级队列(priority queue) 是0个或多个元素的集合,每个元素都有一个优先权。   一般情况下,查找操作用来搜索优先权最大的元素,删除操作用来删除该元素 ,对于优先权相同的元素,可按先进先出次序处理或按任意优先权进行。   由于优先级队列的性质,我们可以使用堆实现它:

代码:
Heap.hpp

#include<ostream>using namespace std;#include<vector>#include<assert.h>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)    {        for(int idx=0;idx<size;++idx)            _heap.push_back(array[idx]);        int root=(_heap.size()-2)>>1;//找到倒数第一个非叶子结点·        for(;root>=0;--root)            _AdjustDown(root);    }    size_t Size()const    {        return _heap.size();    }    bool Empty()const    {        return _heap.empty();    }    size_t Top()const    {        return _heap[0];    }    void Insert(const T& data)    {        _heap.push_back(data);//直接插入到最后一个元素        if(_heap.size()>1)//排成最小堆/最大堆            _AdjustUp();    }    void Remove()//删除堆顶    {        assert(!_heap.empty());        std::swap(_heap[0],_heap[_heap.size()-1]);//将堆顶与最后一个结点交换位置        _heap.pop_back();//最后一个结点出堆,即原来的堆顶        if(_heap.size()>1)        {            int root=(_heap.size()-2)>>1;//找到倒数第一个非叶子结点·            for(;root>=0;--root)            _AdjustDown(root);//将整个树排为最小堆/最大堆        }    }protected:    void _AdjustDown(size_t parent)    {        size_t child=parent*2+1;        size_t size=_heap.size();        while(child<size)        {            Compare com;            if(child+1<size && com(_heap[child+1],_heap[child]))//左孩子>右孩子,将右孩子标记为孩子结点                child+=1;            if(Compare()(_heap[child],_heap[parent]))//孩子结点<小于双亲结点时,将两结点交换位置            {                std::swap(_heap[child],_heap[parent]);                parent=child;                child=parent*2+1;            }            else                return;        }    }    void _AdjustUp()//向上排成最小/大堆    {        size_t child=_heap.size()-1;        size_t parent=(child-1)>>1;        while(child!=0)        {            if(Compare()(_heap[child],_heap[parent]))            {                std::swap(_heap[child],_heap[parent]);                child=parent;                parent=(child-1)>>1;            }            else                return;        }    }private:     std::vector<T> _heap;};

PriorityQueue.hpp

#include<ostream>using namespace std;template<class T, class Compare = Less<T>>class PriorityQueue{public:    PriorityQueue()    {}    PriorityQueue(const T array[],size_t size)    {        _hp=Heap<T,Compare>(array,size);    }    void Push(const T& data)    {        _hp.Insert(data);    }    void Pop()    {        _hp.Remove();    }    const T& Top()const    {        _hp.Top();    }    size_t Size()const    {        return _hp.Size();    }    bool Empty()const    {        return _hp.Empty();    }protected:    Heap<T, Compare> _hp;};

测试代码:

#include"Heap.hpp"#include"PriorityQueue.hpp"void Test(){    int array[]={12,8,3,53,22,77,19,32};    PriorityQueue<int,Less<int>> q(array,sizeof(array)/sizeof(array[0]));    q.Push(9);    q.Pop();}int main(){    Test();    return 0;}
0 0
原创粉丝点击