C++笔记:队列queue、优先队列priority_queue、双端队列deque

本人花三天时间写完,累死,⏬,如果对您有用,请点赞哦~

目录

NO.1 队列

一.什么是队列

二.队列的一些概念

三.C++STL里面的队列(已下称 queue )操作

四.队列例题

NO.2 优先队列

一.什么是优先队列

二.C++STL里面的优先队列(priority_queue)操作

三.优先队列例题

NO.3 双端队列

一.什么是双端队列(deque)

二.C++STL里面的优先队列(priority_queue)操作

三.双端队列例题


NO.1 队列

一.什么是队列

队列与栈、动态数组等一样,是一种线性数据结构,规则为:先加入的元素先被删除,即“先进先出”,与栈恰好相反。队列只能在队尾添加元素,在队头删除元素。

二.队列的一些概念

  • 队头:队列允许删除操作的那一头。
  • 队尾:队列允许插入操作的那一头。
  • 入队:队列的插入操作。
  • 出队:队列的删除操作。
  • 下面是图例:

三.C++STL里面的队列(已下称 queue )操作

#include<queue> //用队列要调用的头文件
queue<int>q; //定义一个名字为q、数据类型为int的队列
q.empty(); //如果队列为空返回true,否则返回false
q.size(); //返回队列中元素的个数
q.pop(); //删除队列首元素但不返回其值
q.front(); //返回队首元素的值,但不删除该元素
q.push(); //在队尾压入新元素
q.back(); //返回队列尾元素的值,但不删除该元素

四.队列例题

在这里插入图片描述

#include<iostream>
#include<queue>
using namespace std;
int main()
{
    int m,n,k;
    cin>>n>>m>>k;
    queue<int>q1,q2;
    for(int i=1;i<=n;i++)q1.push(i);
    for(int i=1;i<=m;i++)q2.push(i);
    while(k--)
    {
        cout<<q1.front()<<" "<<q2.front()<<endl;
        q1.push(q1.front());
        q2.push(q2.front());
        q1.pop();
        q2.pop();
    }
    return 0;
}

NO.2 优先队列

一.什么是优先队列

优先队列与队列差不多,但是有了优先级。优先队列默认会将插入的元素从大到小排序,内部是由堆来完成的。例如在医院里,重症急诊患者肯定不能像普通患者那样依次排队就诊。这时候,我们就需要优先队列,这样就能先访问优先级高的元素。

二.C++STL里面的优先队列(priority_queue)操作

#include<queue> //优先队列要调用的头文件
priority_queue<int>pq; //声明了一个int类型的将元素优先级高的排在前面的优先队列
priority_queue<int,vector<int>,greater<int> > pq_2; /*声明了一个int类型的将
元素优先级低的排在前面的优先队列(要#include<vector>),为了避免>>被认为成右移符
号,在中间最好打上空格。*/
pq.top(); //返回队头元素的值但不删除
pq.empty(); //队列是否为空,空则返回0,否则返回1
pq.size(); //返回队列内元素个数
pq.push(); //插入元素到队尾 (并排序)
pq.pop(); //弹出队头元素

优先队列其实也可以自定义优先级,读者可以在百度上搜,这里就不多说了(小编不了解此知识······),大概是这样:

/定义比较结构
struct cmp1{
    bool operator ()(int &a,int &b){
        return a>b;//最小值优先
    }
};

struct cmp2{
    bool operator ()(int &a,int &b){
        return a<b;//最大值优先
    }
};

//自定义数据结构
struct number1{
    int x;
    bool operator < (const number1 &a) const {
        return x>a.x;//最小值优先
    }
};
struct number2{
    int x;
    bool operator < (const number2 &a) const {
        return x<a.x;//最大值优先
    }
};

三.优先队列例题

题目链接可见:http://codeforces.com/contest/1015/problem/C

代码:

#include<iostream>
#include<queue>
using namespace std;
const int N=1e5+7;
priority_queue<int>q;
int n,m,i,j,k;
long long sum;
int main(){
    cin>>n>>m;
	for(k=1;k<=n;++k){
        scanf("%d%d",&i,&j);
        sum+=i;
        q.push(i-j);
	}
	while(!q.empty()&&sum>m){
        sum-=q.top();
        q.pop();
	}
	if(sum<=m)cout<<n-q.size()<<endl;
	else puts("-1");
}

NO.3 双端队列

一.什么是双端队列(deque)

双端队列(deque)是队列的一种变形,一般队列只能在队尾添加元素(push),在队首删除元素(pop),双端队列则同时在队首或者队尾执行添加和删除工作。

二.C++STL里面的优先队列(priority_queue)操作

#include<deque> //引入双端队列要调用
deque<int>dq; //定义一个int类型的双端队列dq
dq.push_back(); //在队列尾部添加元素,无返回值。
dq.push_front(); //在队列头部添加元素,无返回值;
dq.pop_back(); //删除队列尾部的元素,无返回值;
dq.pop_front(); //删除队列头部的元素,无返回值;
dq.front(); /*获得队列头部元素。此函数返回值为队列的头部元素,
常与pop_front()函数一起,先通过这个 
dq.front()获得队列头部元素,
然后用pop_front()将其从队列中删除;*/
dq.back(); //获得队列尾部元素。此函数返回值为队列的尾部元素,常与pop_back()函数一起,
//先通过back()获得队列头部元素,然后用pop_back()将其从队列中删除;
dq.size(); //获得队列大小。此函数返回队列的大小,返回值是“size_t”类型的数据,
//“size_t”是“unsigned int”的别名;
dq.empty(); //判断队列是否为空。此函数返回队列是否为空,返回值是bool类型。队列空
//:返回true;不空:返回false。

三.双端队列例题

小易老师是非常严厉的,它会要求所有学生在进入教室前都排成一列,并且他要求学生按照身高不递减的顺序排列。有一次,n个学生在列队的时候,小易老师正好去卫生间了。学生们终于有机会反击了,于是学生们决定来一次疯狂的队列,他们定义一个队列的疯狂值为每对相邻排列学生身高差的绝对值总和。由于按照身高顺序排列的队列的疯狂值是最小的,他们当然决定按照疯狂值最大的顺序来进行列队。现在给出n个学生的身高,请计算出这些学生列队的最大可能的疯狂值。小易老师回来一定会气得半死。

输入描述:

输入包括两行,第一行一个整数n(1 ≤ n ≤ 50),表示学生的人数
第二行为n个整数h[i](1 ≤ h[i] ≤ 1000),表示每个学生的身高

输出描述:

输出一个整数,表示n个学生列队可以获得的最大的疯狂值。

如样例所示: 
当队列排列顺序是: 25-10-40-5-25, 身高差绝对值的总和为15+30+35+20=100。
这是最大的疯狂值了。

示例1

输入

5
5 10 25 40 25

输出

100

代码:

#include<iostream>
#include<deque>
#include<algorithm>
using namespace std;
int main()
{
    int n;
    cin>>n;
    int a[50];
    for(int i=0;i<n;i++)
    {
        cin>>a[i];
    }
    sort(a,a+n);
    deque<int> d;
    int l=0,r=n-1;
    d.push_front(a[r]);
    r--;
    while(l<=r){
         if(l<=r){
             d.push_front(a[l++]);
             if(l<=r)
             d.push_back(a[l++]);
         }
         if(l<=r){
              d.push_front(a[r--]);
              if(l<=r)
              d.push_back(a[r--]);
         }
    }
    if(abs(d[n-1]-d[n-2])<abs(d[n-1]-d[0])){
            d.push_front(d.back());
            d.pop_back();
    }
    int res=0;
    for(int i=1;i<n;i++){
        res+=abs(d[i]-d[i-1]);
    }
    cout<<res<<endl;
    return 0;
}

本人花三天时间写完,如果对您有用,请点赞哦~

猜你喜欢

转载自blog.csdn.net/Keven_11/article/details/107844744