当前位置: 首页 > article >正文

备战蓝桥杯 队列和queue详解

目录

队列的概念

队列的静态实现

总代码

stl的queue

队列算法题

1.队列模板题

2.机器翻译

3.海港

双端队列


队列的概念

和栈一样,队列也是一种访问受限的线性表,它只能在表头位置删除,在表尾位置插入,队列是先进先出(FIFO)栈是后进先出(LIFO)

队列的静态实现

我们用一个比较大的数组来表示队列,h表示队头的前一个元素,t表示队尾元素

队列的创建

#include <iostream>
using namespace std;
const int N = 1e5 + 10;
int q[N], h, t;

队列的插入

void push(int x)
{
	q[++t] = x;
}

和顺序表的尾插差不多,时间复杂度是O(1)

队列的删除

我们的删除直接让头指针向前移动一位就行了

void pop()
{
	h++;
}

查询队头元素

h指向的是队头的前一个元素的下标,所以h+1是队头的下标

int front()
{
	return q[h + 1];
}

查询队尾元素

t就是队尾元素的下标

int back()
{
	return q[t];
}

队列判空

当我们只剩一个元素的时候,h指向这个元素的前面,t指向这个元素,如果删除的话,h++ h就和t相等了,这和我们刚开始没有元素的状态也是一致的,所以h==t就是我们判断队列为空的要点

bool empty()
{
	return h == t;
}

队列有效元素个数

由于我们h和t是左开右闭的,所以t-h就是中间的元素个数,比如h指向1,t指向3的时候,下标2,3就是我们的元素,3-1=2就是元素个数是一致的

int size()
{
	return t - h;
}

测试

总代码

#include <iostream>
using namespace std;
const int N = 1e5 + 10;
int q[N], h, t;
void push(int x)
{
	q[++t] = x;
}
void pop()
{
	h++;
}
int front()
{
	return q[h + 1];
}
int back()
{
	return q[t];
}
bool empty()
{
	return h == t;
}
int size()
{
	return t - h;
}
int main()
{
	for (int i = 1; i <= 10; i++)
	{
		push(i);
	}
	while (size())
	{
		cout << front() << " " << back() << endl;
		pop();
	}

	return 0;
}

stl的queue

测试代码

#include <iostream>
#include <queue>
using namespace std;
typedef pair<int, int> PII;
int main()
{

	queue <PII> q;
	for (int i = 1; i <= 10; i++)
	{
		q.push({ i,i * 10 });
	}
	while (!q.empty())
	{
		auto t = q.front();
		int first = t.first;
		int second = t.second;
		cout << first << " " << second << endl;
		q.pop();
	}

}

测试结果

队列算法题

1.队列模板题

#include <iostream>
using namespace std;
const int N = 1e4+10;
int q[N],h,t;

int main()
{
	int n,op,x;
	cin >> n;
	while(n--)
	{
		cin >> op;
		if(op == 1)
		{
			cin >> x;
			q[++t] = x;
		}
		else if(op == 2)
		{
			if(t-h == 0) cout << "ERR_CANNOT_POP" << endl;
			else h++;
		}
		else if(op == 3)
		{
			if(t-h == 0) cout << "ERR_CANNOT_QUERY" << endl;
			else cout << q[h+1] << endl;
		}
		else
		{
			cout << t-h << endl;
		}
	}
}

2.机器翻译

我们可以用队列来模拟这个内存存储的单元格,此外我们还需要一个bool数组来判断某个单词在不在内存中

下面是我们的实现的代码

#include <iostream>
#include <queue>
using namespace std;
const int N = 1010;
bool st[N];
int cnt;
queue <int> q;
int main()
{
	int n,m;
	cin >> m >> n;
	while(n--)
	{
		int x; cin >> x;
		if(st[x]);
		else{
			q.push(x);
			st[x] = true;
			cnt++;
			if(q.size() > m)
			{
				st[q.front()] = false;
				q.pop();
			}
		}
		
		
	}
	cout << cnt << endl;
}

3.海港

这道题我们用队列来模拟,我们用一个数组来记录每个国家的人数,当每个国家从0变1时,种类加1,从1变0时,种类减1

先把每个船的信息入队列,用pair类型,<时间,国家>来入队列,每次入队列判断种类是否加1

每个船的信息入完了之后,要判断队列合不合法,如果队头的时刻和队尾的时刻差值超过24小时,我们就要把第一个时刻的信息出队列,出队列的时候再次判断要不要让种类减1

每次一个信息弄完就打印一下种类

#include <iostream>
#include <queue>
using namespace std;
const int N = 1e5+10;
typedef pair<int,int> PII;
int t,k;
int cnt[N];//记录每个国家的人数,从0到1时种类加1,从1到0时种类减1,其他不变 
int kinds;//记录国家种类 
queue <PII> q;
int main()
{
    int n;
	cin >> n;
	while(n--)
	{
		cin >> t >> k;
		while(k--)
		{
			int x;
			cin >> x;
			q.push({t,x});
			if(cnt[x]++ == 0)
			{
				kinds++;
			}
		}
	    //让队列合法
		while(q.size() && (q.back().first - q.front().first >= 86400)) 
		{
			int tmp;
			tmp = q.front().second;
			if(cnt[tmp]-- == 1)
			{
				kinds--;
			}
			q.pop();
		}
			cout << kinds << endl;
	}	

	
	return 0;
 } 

双端队列

什么是双端队列?

双端队列也是一种特殊的线性表,它允许在表的两端插入和删除元素

我们就不实现它的模拟实现了

我们直接用stl现成的双端队列deque测试一下

头插头删

#include <iostream>
#include <deque>
using namespace std;
struct node {
	int x, y, z;
};
deque <node> q;
int main()
{
	//头插和头删
	for (int i = 1; i <= 5; i++)
	{
		q.push_front({ i,i * 5,i * 10 });
	}
	while (q.size())
	{
		auto t = q.front();
		q.pop_front();
		cout << t.x << " " << t.y << " " << t.z << endl;
	}
}

同理尾插和尾删

#include <iostream>
#include <deque>
using namespace std;
struct node {
	int x, y, z;
};
deque <node> q;
int main()
{
	//尾插和尾删
	for (int i = 1; i <= 5; i++)
	{
		q.push_back({ i,i * 5,i * 10 });
	}
	while (q.size())
	{
		auto t = q.back();
		q.pop_back();
		cout << t.x << " " << t.y << " " << t.z << endl;
	}
}


http://www.kler.cn/a/505855.html

相关文章:

  • 解决 Mac 系统上的 node-sass 问题
  • Spring 核心技术解析【纯干货版】- VIII:Spring 数据访问模块 Spring-Tx 模块精讲
  • 少一点If/Else - 状态模式(State Pattern)
  • 网络编程 - - TCP套接字通信及编程实现
  • Stream流
  • 项目练习:若依管理系统字典功能-Vue前端部分
  • git操作(bitbucket仓库)
  • 数据库(MySQL)练习
  • Android Room 持久化库的介绍及使用方法
  • 力扣经典题目之120.三角形最小路径和
  • PHP智慧小区物业管理小程序
  • MSSQL(Microsoft SQL Server)和 SQL(Structured Query Language)之间的区别
  • 计算机视觉与深度学习:使用深度学习训练基于视觉的车辆检测器(MATLAB源码-Faster R-CNN)
  • 202309 青少年软件编程等级考试C/C++ 二级真题答案及解析(电子学会)
  • qt QPainter setViewport setWindow viewport window
  • LLM实现视频切片合成 前沿知识调研
  • python如何随机生成数组
  • MyBatis-增删改查操作一些细节
  • Spark RPC 学习总结
  • 【数据结构-堆】力扣1834. 单线程 CPU
  • XML配置参数解析
  • ssm框架-springboot学习笔记
  • 探索 Docker 技术奥秘
  • 《零基础Go语言算法实战》【题目 4-10】在不使用任何内置散列表库的情况下设计一个 HashMap
  • 数据分析思维(十一):应用篇——用数据分析解决问题
  • 《OpenCV》——模版匹配