c++【STL栈和队列】基本操作函数和模板习题

文章目录

    • 一、栈和队列
      • CSP-J第一轮常考题
      • 做题方法总结——模拟
    • 二、栈的基本操作函数
    • 三、队列的基本操作函数
    • 四、题目
      • 数组逆序重存放
        • 分析:
      • 【模板】栈
        • 分析
        • 注意
      • 【模板】队列
        • 分析
    • 一点话


今天讲一下STL里面的栈和队列的基本操作,栈和队列都是一种数据结构,他们的共同点是都是线性结构,当然,他俩也有不同的地方,栈是一种先进后出的数据结构,而队列则是一种先进先出的数据结构。

一、栈和队列

可以这样来说,队列就像一个羽毛球盒,从一边放进去就从另一边拿出来,如果从放进去的那一边一边拿,就会造成羽毛损坏,如图
c++【STL栈和队列】基本操作函数和模板习题_第1张图片

而栈则可以看成一个乒乓球盒,也就是说乒乓球盒只有一个口,越先放进去就会被压到最下面,从而就会越后出来,如图
c++【STL栈和队列】基本操作函数和模板习题_第2张图片

CSP-J第一轮常考题

c++【STL栈和队列】基本操作函数和模板习题_第3张图片
这道题虽然看起来有点难懂,但他确是一道栈的题目,也就是说,我们可以吧弹夹看做一个栈,子弹也就是元素,每将一个子弹放入弹夹,就相当于一个元素入栈,这道题目实际上就是在问下列哪一个出栈顺序是不合法的,我们遇到这样的题目可以画一个示意图:
A:c++【STL栈和队列】基本操作函数和模板习题_第4张图片
所以合法;
B:c++【STL栈和队列】基本操作函数和模板习题_第5张图片
所以合法。
C:c++【STL栈和队列】基本操作函数和模板习题_第6张图片
D:c++【STL栈和队列】基本操作函数和模板习题_第7张图片

做题方法总结——模拟

这道题可以让我们更深刻的理解栈的基本概念。遇到这种题目,我们可以利用栈的概念解决,首先先找准目前没有进过栈的第一个数,然后将目前未进栈元素到我们刚刚找的那个元素全部依次进栈,然后查看出栈顺序是否合法,依次模拟,即可得出结果。

二、栈的基本操作函数

push 元素入栈

push 元素入栈
pop 栈顶元素出栈
front 获取栈底元素
size 获取栈长度
empty 栈判空

三、队列的基本操作函数

push 元素入队列
pop 队尾元素出栈
front 获取队头元素
size 获取队列长度
empty 队列判空
top 获取队尾元素

四、题目

数组逆序重存放

题目描述

将一个数组中的值按逆序重新存放。例如,原来的顺序为 8 , 6 , 5 , 4 , 1 8,6,5,4,1 8,6,5,4,1。要求改为 1 , 4 , 5 , 6 , 8 1,4,5,6,8 1,4,5,6,8

输入格式

输入为两行:第一行数组中元素的个数 n n n 1 < n ≤ 100 1 \lt n \le 100 1<n100),第二行是 n n n 个整数,每两个整数之间用空格分隔。

输出格式

输出为一行:输出逆序后数组的整数,每两个整数之间用空格分隔。

样例 #1

样例输入 #1

5
8 6 5 4 1

样例输出 #1

1 4 5 6 8

这道题非常简单,其方法也很多,最常见的方法就是用数组存储,但是这道题的题意刚好符合我们的栈,为了拿栈练练手,这道题我们用栈做:

分析:

我们只需要利用栈先进后出的特点,将输入的数字依次入栈,最后在依次出栈输出即可:直接给代码

#include
using namespace std;
int i,a,x;
stack<int>h;
int main(){
	ios::sync_with_stdio(false);
	cin>>a;
	for(i=0;i<a;i++){
		cin>>x;
		h.push(x);
	}
	for(i=0;i<a;i++){
		x=h.top();
		h.pop();
		cout<<x<<" ";
	}
}

【模板】栈

题目描述

请你实现一个栈(stack),支持如下操作:

  • push(x):向栈中加入一个数 x x x
  • pop():将栈顶弹出。如果此时栈为空则不进行弹出操作,输出 Empty
  • query():输出栈顶元素,如果此时栈为空则输出 Anguei!
  • size():输出此时栈内元素个数。

输入格式

本题单测试点内有多组数据
输入第一行是一个整数 T T T,表示数据组数。对于每组数据,格式如下:
每组数据第一行是一个整数,表示操作的次数 n n n
接下来 n n n 行,每行首先由一个字符串,为 pushpopquerysize 之一。若为 push,则其后有一个整数 x x x,表示要被加入的数, x x x 和字符串之间用空格隔开;若不是 push,则本行没有其它内容。

输出格式

对于每组数据,按照「题目描述」中的要求依次输出。每次输出占一行。

样例 #1

样例输入 #1

2
5
push 2
query
size
pop
query
3
pop
query
size

样例输出 #1

2
1
Anguei!
Empty
Anguei!
0

提示

样例 1 解释
对于第二组数据,始终为空,所以 popquery 均需要输出对应字符串。栈的 size 为 0。

数据规模与约定

对于全部的测试点,保证 1 ≤ T , n ≤ 1 0 6 1 \leq T, n\leq 10^6 1T,n106,且单个测试点内的 n n n 之和不超过 1 0 6 10^6 106,即 ∑ n ≤ 1 0 6 \sum n \leq 10^6 n106。保证 0 ≤ x < 2 64 0 \leq x \lt 2^{64} 0x<264

提示

  • 请注意大量数据读入对程序效率造成的影响。
  • 因为一开始数据造错了,请注意输出的 Empty 不含叹号,Anguei! 含有叹号。

分析

这是一道普及模板题,这道题目是让我们用栈来实现一个栈,这听起来非常拗口,但做起来非常容易,只需要判断输入的是什么指令,在利用栈实现即可:

注意

这道题需要注意一个地方,他会有很多次指令,再一次指令弄完以后,一定要记得清空栈哦!

//B3614【模板】栈 
#include
using namespace std;
int n,i,j,k,x,z;
string c;
stack<int>h;
int main(){
	ios::sync_with_stdio(false);
	cin>>n;
	for(i=1;i<=n;i++){
		cin>>k;
		for(j=1;j<=k;j++){
			for(z=1;z<=h.size();z++)//清空栈
				h.top();
			cin>>c;
			if(c=="push"){
				cin>>x;
				h.push(x);
				continue;
			}
			if(c=="pop"){
				if(!h.size()){
					cout<<"Empty"<<endl;
					continue;
				}
				else 
					h.pop();	
			}
			if(c=="query"){
				if(h.size()==0){
					cout<<"Anguei!"<<endl;
					continue;
				}
				else {
					cout<<h.top()<<endl;
					continue;
				}
			}
			if(c=="size")
				cout<<h.size()<<endl;
		}
	}
}

【模板】队列

题目描述

请你实现一个队列(queue),支持如下操作:

  • push(x):向队列中加入一个数 x x x
  • pop():将队首弹出。如果此时队列为空,则不进行弹出操作,并输出 ERR_CANNOT_POP
  • query():输出队首元素。如果此时队首为空,则输出 ERR_CANNOT_QUERY
  • size():输出此时队列内元素个数。

输入格式

第一行,一个整数 n n n,表示操作的次数。

接下来 n n n 行,每行表示一个操作。格式如下:

  • 1 x,表示将元素 x 加入队列。
  • 2,表示将队首弹出队列。
  • 3,表示查询队首。
  • 4,表示查询队列内元素个数。

输出格式

输出若干行,对于每个操作,按「题目描述」输出结果。

每条输出之间应当用空行隔开。

样例 #1

样例输入 #1

13
1 2
3
4
1 233
3
2
3
2
4
3
2
1 144
3

样例输出 #1

2
1
2
233
0
ERR_CANNOT_QUERY
ERR_CANNOT_POP
144

提示

样例解释
首先插入 2,队首为 2、队列内元素个数为 1
插入 233,此时队首为 2
弹出队首,此时队首为 233
弹出队首,此时队首为空。
再次尝试弹出队首,由于队列已经为空,此时无法弹出。
插入 144,此时队首为 144

数据规模与约定

对于 100 % 100\% 100% 的测试数据,满足 n ≤ 10000 n\leq 10000 n10000,且被插入队列的所有元素值是 [ 1 , 1000000 ] [1, 1000000] [1,1000000] 以内的正整数。

分析

这道题依旧是一道模板题,本题就比较仁慈了,不用每次清空队列,也省下了很多时间,且思路和上一道题一样,用一个队列模拟队列即可

#include
using namespace std;
string f;
int n,i,k;
queue<int>h;
int main(){
	ios::sync_with_stdio(false);
	cin>>n;
	for(i=1;i<=n;i++){
		cin>>f;
		if(f=="1"){
			cin>>k;
			h.push(k);
			continue;
		}
		if(f=="2"){
			if(h.size()==0){
				cout<<"ERR_CANNOT_POP"<<endl;
				continue;
			}
			else {
				h.pop();
				continue;
			}
		}
		if(f=="3"){
			if(h.size()==0){
				cout<<"ERR_CANNOT_QUERY"<<endl;
				continue;
			}
			else{
				cout<<h.front()<<endl;
				continue;
			}
		}
		if(f=="4")
			cout<<h.size()<<endl;
	} 
}

一点话

大家再学新知识点的时候,推荐大家去做一下洛谷上面的相应模板题,这样没有太大的思维难度,也能帮助你熟悉相应操作,难度适中,很适合入门!

今天就讲到这里了,下次再见!!!

你可能感兴趣的:(数据结构与STL,题目解析,c++,数据结构,算法)