【C++】STL队列和栈的使用

本文通过两个具体的算法竞赛题目,详细介绍了C++ STL中的队列和栈的使用方法。第一个题目演示了如何利用队列实现一个卡片游戏中的牌堆操作;第二个题目则展示了如何用栈解决铁轨车厢重新排列的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C++的STL标准模板库提供了队列和栈的基本操作。下面通过两个demo分别介绍STL队列和STL栈的使用。

Demo1:STL队列

【题目】卡片游戏(题目来自刘汝佳《算法竞赛入门》)

桌上又一叠牌,从第一张牌(即位于顶面的牌)开始从上往下依次编号为1~n。当至少还剩两张牌时进行以下操作:把第一张牌扔掉,然后把新的第一张放到整叠牌的最后。输入n,输出每次扔掉的牌,以及最后剩下的牌。

样例输入:7

样例输出:1 3 5 7 4 2 6

【分析】这些牌就是一个先进先出(FIFO)的队列,每次对排头的两张进行操作,第一张出队列,第二张放到队尾。

【代码】

#include<cstdio>
#include<queue>
using namespace std;

int main()
{
	queue<int> q;
	int n;
	scanf("%d",&n);
	for(int i = 0;i < n;i++)
	{
		q.push(i+1);
	}
	while(q.size()>=2)
	{
		printf("%d\t",q.front());//输出需要队头第一张,并出队列
		q.pop();
		q.push(q.front());//将队头第二张放到队尾
		q.pop();
	}
	printf("%d\n",q.front());//输出剩余的最后一张
	return 0;
}


Demo2:STL堆栈

【题目】铁轨(题目来自刘汝佳《算法竞赛入门》)

某城市有一个火车站铁轨铺设如图,有n节车厢从A方向驶入车站,按进站顺序编号为1~n。你的任务是让它们按照某种特定的顺序进入B方向的铁轨并驶出车站。为了重组车厢,你可以借助中转站C。这是一个可以停放任意多节车厢的车站。但由于末端封顶,驶入C的车厢必须按照相反的顺序驶出C。对于每个车厢,一旦从A移入C,就不能再回到A了,一旦C移入B,就不能回到C了,换句话说,在任意时刻,只有两种选择:A->C,C->B。


样例输入:

5

1 2 3 4 5

5

5 4 1 2 3

6 5 4 3 2 1

样例输出:

Yes

No

Yes


【分析】A、B车站为队列,C站位LIFO栈。将A车站队列初始化为1~n,B车站队列初始化为用户输入的顺序,进行以下循环,直到B队列为空:

1.如果A车站的队头和B车站的队头相等,直接将A车站对头列车开到B车站(A、B队列均进行出队列操作)。

2.否则如果C栈顶元素和B队头元素相等,则将C的栈顶列车驶入B(C出栈操作,B出队列操作)。

3.否则如果A队列不为空,将A队列队头元素入C栈,

4.否则标记不成功,跳出循环。  

【代码】

#include <cstdio>
#include <stack>
#include <queue>
using namespace std;

int main()
{
	int n,temp;
	while(scanf("%d",&n)==1)
	{
		stack<int> c;
		queue<int> a,b;
		for(int i=1;i<=n;i++)
		{
			scanf("%d",&temp);
			a.push(i);
			b.push(temp);
		}
		
		int ok=1;
		while(b.size()!=0)
		{
			if(a.size()!=0&&a.front()==b.front())
			{a.pop();b.pop();}
			else if(c.size()!=0 && b.front()==c.top())
			{b.pop();c.pop();}
			else if(a.size()!=0)
			{c.push(a.front());a.pop();}
			else 
			{ok=0;break;}
		}
		if(ok)
			printf("Yes");
		else
			printf("No");
	}
	return 0;	
}



### C++ STL队列的用法及区别 #### (Stack) 是一种后进先出(LIFO, Last In First Out)的数据结构。在 C++ STL 中,`stack` 是一种适配器容器,基于其他序列容器(如 `vector`, `deque` 或 `list`)。默认情况下,`stack` 使用 `deque` 作为底层容器。 要使用,需包含头文件 `<stack>`: ```cpp #include <stack> ``` 创建并操作的方式如下所示: ```cpp std::stack<int> s; s.push(10); // 向顶添加元素 s.push(20); if (!s.empty()) { std::cout << "Top element is: " << s.top() << '\n'; // 访问顶元素 } s.pop(); // 移除顶元素 ``` #### 队列(Queue) 队列则遵循先进先出(FIFO, First In First Out)的原则。同样地,在 C++ STL 中,`queue` 也是一种适配器容器,默认也采用 `deque` 实现[^1]。 引入必要的头文件: ```cpp #include <queue> ``` 下面展示如何定义以及操控队列对象: ```cpp std::queue<std::string> q; q.push("hello"); // 插入新元素到队尾 q.push("world"); while (!q.empty()) { std::cout << q.front() << ' '; // 输出队首元素 q.pop(); // 删除队首元素 } // 输出结果为:"hello world" ``` 除了基本功能外,还可以利用双端队列 `deque` 来构建更复杂的逻辑,比如循环缓冲区等特殊应用场景下的自定义行为[^2]。 对于两者的主要差异在于它们各自的操作模式——一个是 LIFO 而另一个则是 FIFO;此外就是具体方法上的不同之处,例如访问顶部/前端元素的方法名有所变化(`top()` vs `front()`)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值