C++——std::Priority_queue

写在前面

这一部分学习一下优先级队列这样一种STL容器。priority_ queue 优先级队列是一个拥有权值概念的单向队列queue,在这个队列中,所有元素是按优先级排列的(也可以认为queue是个按进入队列的先后做为优先级的优先级队列——先进入队列的元素优先权要高于后进入队列的元素)。在计算机操作系统中,优先级队列的使用是相当频繁的,进线程调度都会用到。在STL的具体实现中,priority_queue也是以别的容器作为底部结构,再根据堆的处理规则来调整元素之间的位置。

头文件包含

要在程序中使用priority_queue需要包含queue的头文件。

#include <queue>  

priority_ queue::priority_queue

构造一个优先级队列,可以直接构造一个空队列或者是现有某基础容器对象的拷贝。参考:priority_queue Class——MSDN,其构造方法一共有七种:

priority_queue();

explicit priority_queue(const Traits&_comp);

priority_queue(const Traits&_comp, const container_type& _Cont);

priority_queue(const priority_queue& right);

template <class InputIterator>  
priority_queue(InputIterator first, InputIterator last);

template <class InputIterator>  
priority_queue(InputIterator first, InputIterator last, const Traits&_comp);

template <class InputIterator>  
priority_queue(InputIterator first, InputIterator last, const Traits&_comp, const container_type& _Cont);

其中,各参数含义如下:

  • _ comp:是constTraits的比较函数,用来对队列中的元素进行排列。默认为基本容器的默认排序函数(由小到大);
  • _Cont:通过拷贝容器的方式创造队列的那个基本容器。
  • right:通过拷贝另一个队列的方式创造一个优先级队列的那个队列。
  • first:通过拷贝某一个容器来创建一个优先级队列的容器中的第一个元素。
  • last:通过拷贝某一个容器来创建一个优先级队列的容器中的最后一个元素。

具体实例代码可参考:

   // The first member function declares priority_queue  
   // with a default vector base container  
   priority_queue <int> q1;

   // Explicitly declares a priority_queue with nondefault  
   // deque base container  
   priority_queue <int, deque <int> > q2;  

   // The third member function declares a priority_queue   
   // with a vector base container and specifies that the comparison   
   // function greater is to be used for ordering elements  
   priority_queue <int, vector<int>, std::greater<int> > q3;  

   // The fourth member function declares a priority_queue and  
   // initializes it with elements copied from another container:  
   // first, inserting elements into q1, then copying q1 elements into q4  
   q1.push( 100 );  
   q1.push( 200 );  
   priority_queue <int> q4( q1 );  

   // The fifth member function declares and  
   // initializes a priority_queue q5 by copying the  
   // range v5[ first,  last) from vector<int> v5 {10,20,30}
   priority_queue <int> q5( v5.begin( ), v5.begin( ) + 2 );  

   // The sixth member function declares a priority_queue q6  
   // with a comparison function greater and initializes q6  
   // by copying the range v5[ first,  last) from vector v5  
   priority_queue <int, vector<int>, std::greater<int> > q6( v5.begin( ), v5.begin( ) + 2 );  

Member functions

这里写图片描述

1.empty()
判断优先级队列是否为空。示例代码如下:

// priority_queue::empty
#include <iostream>       // std::cout
#include <queue>          // std::priority_queue

int main ()
{
  std::priority_queue<int> mypq;
  int sum (0);

  for (int i=1;i<=10;i++) mypq.push(i);

  while (!mypq.empty())
  {
     sum += mypq.top();
     mypq.pop();
  }

  std::cout << "total: " << sum << '\n';

  return 0;
}

//Output:
//total: 55

2.size()
返回优先级队列中元素的个数。示例代码如下:

// priority_queue::size
#include <iostream>       // std::cout
#include <queue>          // std::priority_queue

int main ()
{
  std::priority_queue<int> myints;
  std::cout << "0. size: " << myints.size() << '\n';

  for (int i=0; i<5; i++) myints.push(i);
  std::cout << "1. size: " << myints.size() << '\n';

  myints.pop();
  std::cout << "2. size: " << myints.size() << '\n';

  return 0;
}

//Output:

//0. size: 0
//1. size: 5
//2. size: 4

3.top()
获取队列顶层元素。示例代码如下:

// priority_queue::top
#include <iostream>       // std::cout
#include <queue>          // std::priority_queue

int main ()
{
  std::priority_queue<int> mypq;

  mypq.push(10);
  mypq.push(20);
  mypq.push(15);

  std::cout << "mypq.top() is now " << mypq.top() << '\n';

  return 0;
}

//Output:
//mypq.top() is now 20

4.push()
向队列中插入元素。示例代码如下:

// priority_queue::push/pop
#include <iostream>       // std::cout
#include <queue>          // std::priority_queue

int main ()
{
  std::priority_queue<int> mypq;

  mypq.push(30);
  mypq.push(100);
  mypq.push(25);
  mypq.push(40);

  std::cout << "Popping out elements...";
  while (!mypq.empty())
  {
     std::cout << ' ' << mypq.top();
     mypq.pop();
  }
  std::cout << '\n';

  return 0;
}

//Output:
//Popping out elements... 100 40 30 25

5.pop()
删除队列顶部元素。示例代码如下:

// priority_queue::push/pop
#include <iostream>       // std::cout
#include <queue>          // std::priority_queue

int main ()
{
  std::priority_queue<int> mypq;

  mypq.push(30);
  mypq.push(100);
  mypq.push(25);
  mypq.push(40);

  std::cout << "Popping out elements...";
  while (!mypq.empty())
  {
     std::cout << ' ' << mypq.top();
     mypq.pop();
  }
  std::cout << '\n';

  return 0;
}

//Output:
//Popping out elements... 100 40 30 25

6.emplace()
构造并向队列中插入一个元素。示例代码如下:

// priority_queue::emplace
#include <iostream>       // std::cout
#include <queue>          // std::priority_queue
#include <string>         // std::string

int main ()
{
  std::priority_queue<std::string> mypq;

  mypq.emplace("orange");
  mypq.emplace("strawberry");
  mypq.emplace("apple");
  mypq.emplace("pear");

  std::cout << "mypq contains:";
  while (!mypq.empty())
  {
     std::cout << ' ' << mypq.top();
     mypq.pop();
  }
  std::cout << '\n';

  return 0;
}

7.swap()
交换两个队列的内容。示例代码如下:

// priority_queue::swap
#include <iostream>       // std::cout
#include <queue>          // std::priority_queue

int main ()
{
  std::priority_queue<int> foo,bar;
  foo.push (15); foo.push(30); foo.push(10);
  bar.push (101); bar.push(202);

  foo.swap(bar);

  std::cout << "size of foo: " << foo.size() << '\n';
  std::cout << "size of bar: " << bar.size() << '\n';

  return 0;
}

//Output:

//size of foo: 2
//size of bar: 3

VS2008Priority_queue源代码

参考博客:STL系列之五 priority_queue 优先级队列,VS2008中priority_queue源代码如下:

//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  
};  

此外,参考博客:priority_queue的用法,可以通过堆算法实现类似功能,VS2008中源代码可看做是这个的升级版。代码如下:

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

class priority_queue
{
    private:
        vector<int> data;

    public:
        void push( int t ){ 
            data.push_back(t); 
            push_heap( data.begin(), data.end()); 
        }

        void pop(){
            pop_heap( data.begin(), data.end() );
            data.pop_back();
        }

        int top() { return data.front(); }
        int size() { return data.size(); }
        bool empty() { return data.empty(); }
};

写在后面

还有queue、stack、heap的用法没有整理。

猜你喜欢

转载自blog.csdn.net/zy2317878/article/details/80597318