【用法详解】C++-STL 队列queue与优先队列priority_queue的用法详解与学习心得

【C++-STL 队列与优先队列用法详解】

1、队列queue

queue 模板类的定义在头文件中。
与stack 模板类很相似,queue 模板类也需要两个模板参数,一个是元素类型,一个容器类
型,元素类型是必要的,容器类型是可选的,默认为deque 类型。
定义queue 对象的示例代码如下:
queue q1;
queue q2;
queue 的基本操作有:
入队,如例:q.push(x); 将x 接到队列的末端。
出队,如例:q.pop(); 弹出队列的第一个元素,注意,并不会返回被弹出元素的值。
访问队首元素,如例:q.front(),即最早被压入队列的元素。
访问队尾元素,如例:q.back(),即最后被压入队列的元素。
判断队列空,如例:q.empty(),当队列空时,返回true。
访问队列中的元素个数,如例:q.size()

【示例代码1】

#include 
#include 
using namespace std;

int main() {
   int e,m;
    int len;
    queue q;
    for(int i=0;i<10;i++){
        q.push(i);//入队操作,q.push(x); 将x接到队列的末端
    }

    if(!q.empty()){//q.empty(),当队列空时,返回true
        cout<<"队列非空"<

 

2、优先队列

 

priority_queue<int> p;

【常用函数】  

(1)priority_queue::empty
 判断队列是否为空(也即是size是否为0),是则返回true,否则返回false。优先队列的此成员函数实际上调用底层容器的同名函数。
(2)priority_queue::size
 返回队列中元素的个数。此函数实际上调用底层容器的同名函数。这个函数也可以用于判断队列是否为空。
(3)priority_queue::top
 返回队头元素的常引用,队头元素是在所设定的比较关系下最大也即优先级最高的元素。此函数实际上调用底层容器的front函数。
(4)priority_queue::pop
 清除队头元素。
(5)priority_queue::push给队列插入元素,新元素会按其优先级被排列到适当位置。

q.size();//返回q里元素个数
q.empty();//返回q是否为空,空则返回1,否则返回0
q.push(k);//在q的末尾插入k
q.pop();//删掉q的第一个元素
q.top();//返回q的第一个元素

3、less和greater优先队列

 

  优先队列是优先级高的在队首,定义优先级大小的方式是传入一个算子的参数比较a, b两个东西,返回truea的优先级

 

  默认是less算子也就是返回ab,小的优先级高。

  如果是默认的less算子,值大的优先级高,自然默认的优先队列大的先出队。

  如果是使用greater算子,值小的优先级高,优先队列小的先出队。

priority_queue ,less > p;
priority_queue ,greater > q;

【默认less算子--优先输出大数据】  

  priority_queue模板类有三个模板参数,第一个Type是元素类型,第二个Container为容器类型,第三个Functional是比较算子。其中后两个都可以省略,默认容器为vector,默认算子为less:

  less算子即默认算子为:大的往前排,小的往后排(出队时队列头的元素出队,即大者先出队)。

#include  
#include  
using namespace std;  
  
int main(){  
    priority_queue p;  
    p.push(1);  
    p.push(2);  
    p.push(8);  
    p.push(5);  
    p.push(43);  
     while(!q.empty()){  
        cout<

【greater算子--优先输出小数据】 

  greater算子即默认算子为:小的往前排,大的往后排(出队时队列头的元素出队,即小者先出队)。

priority_queue, greater > p;  
#include  
#include  
using namespace std;  
  
int main(){  
    priority_queue, greater >p;  
    p.push(1);  
    p.push(2);  
    p.push(8);  
    p.push(5);  
    p.push(43);  
    while(!q.empty()){  
        cout<

 

【自定义算子--重载默认的<符号】

 

#include 
#include 
using namespace std;
class T
{
    public:
    int x, y, z;
    T(int a, int b, int c):x(a), y(b), z(c) { }

};

bool operator < (const T &t1, const T &t2)
{
    return t1.z < t2.z; // 按照z 的顺序来决定t1 和t2 的顺序
}


int main()
{
    priority_queue q;//使用模板T的自定义比较方法
    q.push(T(4,4,3));
    q.push(T(2,2,5));
    q.push(T(1,5,4));
    q.push(T(3,3,6));
    while (!q.empty())
    {
        T t = q.top(); q.pop();
        cout << t.x << " " << t.y << " " << t.z << endl;

    }
    return 0;
}

个人更喜欢把自定义算子写成友元的,写进类里:struct情况类似

为了更好地理解自定义算子,下面给出了两个示例代码,

其中一个为上面例子中使用struct,且把自定义算子写进struct内部的情况

另一个为测试Dijkstra模板中HeapNode的测试代码;

【源代码1】    

#include 
#include 
using namespace std;

struct T
{
    public:
    int x, y, z;
    T(int a, int b, int c):x(a), y(b), z(c) { }
    friend bool operator < (const T &t1, const T &t2)//自定义less算子,优先输出大数据
    {   ////z值小的往前排,z值大的往后排(出队时序列尾的元素出队,即z值大者先出队)
        return t1.z < t2.z; // 按照z 的顺序来决定t1 和t2 的顺序,优先输出z值大的大数据
       // return t2.z > t1.z;
    }
};

int main()
{
    priority_queue q;//使用模板T的自定义比较方法
    q.push(T(4,4,3));
    q.push(T(2,2,5));
    q.push(T(1,5,4));
    q.push(T(3,3,6));
    while (!q.empty())
    {
        T t = q.top();
        q.pop();
        cout << t.x << " " << t.y << " " << t.z << endl;

    }
    return 0;
}

【测试结果1】     

3 3 6
2 2 5
1 5 4
4 4 3

【源代码2】     

#include 
#include 
using namespace std;

struct HeapNode //Dijkstra算法用到的优先队列的节点
{
    int d,u;
    HeapNode(int d,int u):d(d),u(u){}
    bool operator < (const HeapNode &rhs)const //自定义less算子,优先输出大数据
    {   //按照d的顺序来决定自身HeapNode和rhs的顺序,优先输出d值大的大数据
        //return d > rhs.d; 这两种写法是一样的
         return rhs.d q;//使用模板T的自定义比较方法
    q.push(HeapNode(4,3));
    q.push(HeapNode(2,5));
    q.push(HeapNode(1,4));
    q.push(HeapNode(3,6));
    while (!q.empty())
    {
        HeapNode n = q.top(); q.pop();
        cout << n.d << " " << n.u << endl;

    }
    return 0;
}

【测试结果2】     

1 4
2 5
3 6
4 3

以下例子帮助理解大根堆、小根堆:

#include 
#include 
#include 
using namespace std;
 
int main(int argc, char** argv) { 
	//priority_queue,greater>q;//greater是小根堆,从小到大输出
	priority_queue,less>q;     // less是大根堆, 从大到小输出 
    //priority_queueq默认从大到小排序(大根堆)
    int n;
    int x;
    while(cin>>n){
    	for(int i=0;i>x;
    		q.push(x);
		}
    	while(!q.empty()){
		    int x=q.top();
		    cout<

相关链接1

 

相关链接2

相关链接3

   

你可能感兴趣的:(学习笔记与用法总结)