您的位置:首页 > 产品设计 > UI/UE

STL系列之五 priority_queue 优先级队列

2015-03-19 22:09 399 查看
priority_queue 优先级队列是一个拥有权值概念的单向队列queue,在这个队列中,所有元素是按优先级排列的(也可以认为queue是个按进入队列的先后做为优先级的优先级队列——先进入队列的元素优先权要高于后进入队列的元素)。在计算机操作系统中,优先级队列的使用是相当频繁的,进线程调度都会用到。在STL的具体实现中,priority_queue也是以别的容器作为底部结构,再根据堆的处理规则来调整元素之间的位置。下面给出priority_queue的函数列表和VS2008中priority_queue的源代码,本文中与heap有关的函数参见《STL系列之四
heap 堆》。
priority_queue函数列表
函数描述      by MoreWindows( http://blog.csdn.net/MoreWindows )
构造析构
priority_queue <Elem> c
 创建一个空的queue 。

注:priority_queue构造函数有7个版本,请查阅MSDN
数据访问与增减
c.top()返回队列头部数据
c.push(elem)在队列尾部增加elem数据
 c.pop()队列头部数据出队
其它操作
c.empty()判断队列是否为空
c.size()返回队列中数据的个数

 
可以看出priority_queue的函数列表与栈stack的函数列表是相同的。

 

VS2008中priority_queue 优先级队列的源代码

友情提示:初次阅读时请注意其实现思想,不要在细节上浪费过多的时间

 

[cpp] view
plaincopy

//VS2008中 priority_queue的定义 MoreWindows整理( http://blog.csdn.net/MoreWindows )  

template<class _Ty, class _Container = vector<_Ty>, class _Pr = less<typename _Container::value_type> > //默认以vector为容器的  

class priority_queue  

{   // priority queue implemented with a _Container  

public:  

    typedef _Container container_type;  

    typedef typename _Container::value_type value_type;  

    typedef typename _Container::size_type size_type;  

    typedef typename _Container::reference reference;  

    typedef typename _Container::const_reference const_reference;  

  

    priority_queue() : c(), comp()  

    {   // construct with empty container, default comparator  

    }  

  

    explicit priority_queue(const _Pr& _Pred) : c(), comp(_Pred)  

    {   // construct with empty container, specified comparator  

    }  

  

    priority_queue(const _Pr& _Pred, const _Container& _Cont) : c(_Cont), comp(_Pred)  

    {   // construct by copying specified container, comparator  

        make_heap(c.begin(), c.end(), comp); //参见《STL系列之四 heap 堆的相关函数》  

    }  

  

    template<class _Iter>  

    priority_queue(_Iter _First, _Iter _Last) : c(_First, _Last), comp()  

    {   // construct by copying [_First, _Last), default comparator  

        make_heap(c.begin(), c.end(), comp);  

    }  

  

    template<class _Iter>  

    priority_queue(_Iter _First, _Iter _Last, const _Pr& _Pred) : c(_First, _Last), comp(_Pred)  

    {   // construct by copying [_First, _Last), specified comparator  

        make_heap(c.begin(), c.end(), comp);  

    }  

  

    template<class _Iter>  

    priority_queue(_Iter _First, _Iter _Last, const _Pr& _Pred, const _Container& _Cont) : c(_Cont), comp(_Pred)  

    {   // construct by copying [_First, _Last), container, and comparator  

        c.insert(c.end(), _First, _Last);  

        make_heap(c.begin(), c.end(), comp);  

    }  

  

    bool empty() const  

    {   // test if queue is empty  

        return (c.empty());  

    }  

  

    size_type size() const  

    {   // return length of queue  

        return (c.size());  

    }  

  

    const_reference top() const  

    {   // return highest-priority element  

        return (c.front());  

    }  

  

    reference top()  

    {   // return mutable highest-priority element (retained)  

        return (c.front());  

    }  

  

    void push(const value_type& _Pred)  

    {   // insert value in priority order  

        c.push_back(_Pred);  

        push_heap(c.begin(), c.end(), comp);  

    }  

  

    void pop()  

    {   // erase highest-priority element  

        pop_heap(c.begin(), c.end(), comp);  

        c.pop_back();  

    }  

  

protected:  

    _Container c;   // the underlying container  

    _Pr comp;   // the comparator functor  

};  

下面先给出优级先级队列的使用范例。

[cpp] view
plaincopy

//优先级队列 priority_queue by MoreWindows( http://blog.csdn.net/MoreWindows )  

// 支持 empty() size() top() push() pop() 与stack的操作函数全部一样  

//by MoreWindows  

#include <queue>  

#include <list>  

#include <cstdio>  

using namespace std;  

int main()  

{  

    //优先级队列默认是使用vector作容器。  

    priority_queue<int> a;  

    priority_queue<int, list<int>> b; //可以这样声明,但无法使用  

    int i;  

    //压入数据  

    for (i = 0; i < 10; i++)  

    {  

        a.push(i * 2 - 5);  

        //b.push(i); //编译错误  

    }  

    //优先级队列的大小  

    printf("%d\n", a.size());  

    //取优先级队列数据并将数据移出队列  

    while (!a.empty())  

    {  

        printf("%d ", a.top());  

        a.pop();  

    }  

    putchar('\n');  

    return 0;  

}  

下面程序是针对结构体的,对数据的比较是通过对结构体重载operator()。

程序功能是模拟排队过程,每人有姓名和优先级,优先级相同则比较姓名,开始有5个人进入队列,然后队头2个人出队,再有3个人进入队列,最后所有人都依次出队,程序会输出离开队伍的顺序。

[cpp] view
plaincopy

//by MoreWindows( http://blog.csdn.net/MoreWindows )  

#include <queue>  

#include <cstring>  

#include <cstdio>  

using namespace std;  

//结构体  

struct Node  

{  

    char szName[20];  

    int  priority;  

    Node(int nri, char *pszName)  

    {  

        strcpy(szName, pszName);  

        priority = nri;  

    }  

};  

//结构体的比较方法 改写operator()  

struct NodeCmp  

{  

    bool operator()(const Node &na, const Node &nb)  

    {  

        if (na.priority != nb.priority)  

            return na.priority <= nb.priority;  

        else  

            return strcmp(na.szName, nb.szName) > 0;  

    }  

};  

void PrintfNode(Node &na)  

{  

    printf("%s %d\n", na.szName, na.priority);  

}  

int main()  

{  

    //优先级队列默认是使用vector作容器,底层数据结构为堆。  

    priority_queue<Node, vector<Node>, NodeCmp> a;  

  

    //有5个人进入队列  

    a.push(Node(5, "小谭"));  

    a.push(Node(3, "小刘"));  

    a.push(Node(1, "小涛"));  

    a.push(Node(5, "小王"));  

  

    //队头的2个人出队  

    PrintfNode(a.top());  

    a.pop();  

    PrintfNode(a.top());  

    a.pop();  

    printf("--------------------\n");  

  

    //再进入3个人  

    a.push(Node(2, "小白"));  

    a.push(Node(2, "小强"));  

    a.push(Node(3, "小新"));  

  

    //所有人都依次出队  

    while (!a.empty())  

    {  

        PrintfNode(a.top());  

        a.pop();  

    }  

  

    return 0;  

}  

读者可以将上面结构体Node改成类来试下,答案2天后发到本篇的评论中。

 

 

转载请标明出处,原文地址:http://blog.csdn.net/morewindows/article/details/6976468
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  stl c++