C++ STL学习之七:配接器priority_queue深入学习

来源:互联网 发布:硬盘坏了数据还在吗 编辑:程序博客网 时间:2024/05/22 09:51
 priority_queue是一个带有权值观念的队列,因此取出元素的时候只能取出权值最大的元素。

 priority_queue完全以底层容器为根据(缺省为vector),加上heap(greater,less)处理规则实现。

 priority_queue 不能用list 实现,因为list 只支持双向迭代器,而不支持随机迭代器。

示例程序:


<span style="font-size:18px;">#include<iostream>#include<iterator>#include<vector>#include<queue>#include<algorithm>using namespace std;int main(int argc,char *argv[]){int a[]={12,56,96,3,4,7,9,5};//prioritypriority_queue<int,vector<int>,greater<int> > mypriority(a,a+8);while(!mypriority.empty()){cout<<mypriority.top()<<" ";mypriority.pop();}cout<<endl;//make heapmake_heap(a,a+8,less<int>());copy(a,a+8,ostream_iterator<int>(cout,""));cout<<endl;sort(a,a+8);copy(a,a+8,ostream_iterator<int>(cout,""));cout<<endl;sort_heap(a,a+8,less<int>());copy(a,a+8,ostream_iterator<int>(cout,""));cout<<endl;return 0;}</span><span style="font-size: 14px;"></span>

shenhuayu@shenhuayu-VirtualBox ~/src $ g++ stltest.cpp -g -o mystltest
shenhuayu@shenhuayu-VirtualBox ~/src $ ./mystltest
3 4 5 7 9 12 56 96 
96 56 1254 7 9 3
3 4 579 12 56 96
4 5 7912 56 96 3


make_heap() 将容器的元素构造成二叉堆,传递的是less,即构造的是大堆,把大堆层序遍历的结果存入数组,再调用sort() 进行排序,内部调用

的实际算法不一定,可以是堆排序、插入排序、选择排序等等,跟踪进去发现调用的是插入排序;当然也可以直接指定使用堆排序 sort_heap(调用

者必须已经是堆了,也就是前面已经先调用了make_heap,而且大小堆类型得匹配),与make_heap 一样,第三个参数传递的都是函数对象的用

法。sort 和 sort_heap 默认都是从小到大排序,除非重载的版本传递了第三个参数,如下,第三个参数可以是函数指针,也可以是函数对象:



// order heap by repeatedly popping, using operator<template<class _RanIt> inlinevoid sort_heap(_RanIt _First, _RanIt _Last);// order heap by repeatedly popping, using _Predtemplate < class _RanIt,         class _Pr > inlinevoid sort_heap(_RanIt _First, _RanIt _Last, _Pr _Pred);

priority_queue 的源码:

// TEMPLATE CLASS priority_queuetemplate < class _Ty,         class _Container = vector<_Ty>,         class _Pr = less<typename _Container::value_type> >class priority_queue{    // priority queue implemented with a _Containerpublic:    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);    }    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};
priority_queue 的实现稍微复杂一点,可以传递3个参数,而且有两个成员,comp 即自定义比较逻辑,默认是less<value_type>,在构造函数中

调用make_heap函数构造二叉堆,comp 主要是用于构造二叉堆时的判别,如果是less 则构造大堆,如果传递greater 则构造小堆.






0 0