11.stack和queue

文章介绍了栈和队列这两种线性数据结构在OI(在线算法竞赛)中的应用,以及如何使用STL(标准模板库)中的stack和queue。栈遵循“后进先出”原则,常用于括号匹配等问题;队列遵循“先进先出”原则,常用于模拟排队等场景。文章详细阐述了栈和队列的基本操作,如push、pop、top、empty和size,并给出了相关题目示例。

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

一、栈

1.简介

栈是 OI 中常用的一种满足一定约束的线性数据结构。栈只允许在其中一端插入和删除元素,这一端被称为栈顶,另一端被称为栈底。故而栈满足一种“先进后出的原则”。就像放进收纳盒的书,只有拿出上面的书之后,才能取出下面的书。

我们可以使用普通的数组来模拟栈,也可以使用 vector,但是 STL 中有更方便和使用方式更明确的 stack

2.定义

#include <stack>

使用 STL 的栈需要首先在代码的开头引入这个头文件。

stack<T> s;

T T T 表示我们所定义的数组存储数据的类型。它可以是 int, double 这样的基本数据类型,可以是 typedef 之后的代词,也可以是自定义的结构体类型,甚至可以是其他的 STL 类型。

typedef long long ll;
stack<int> a;
stack<double> b;
stack<ll> c;
stack<node> d;
stack<vector<ll> >e;

一开始定义好的栈的长度为 0 0 0,代表一个空的栈。

3.基本操作

(1)插入一个元素 push()

stack<ll> s;//{}
s.push(1);//{1}
s.push(2);//{1, 2}
s.push(3);//{1, 2, 3}

vector 不同的是,stack 无需指定 push_back()。因为 stack 只会从栈顶插入。

在栈中无法像 vector 那样对里面的任意元素进行赋值操作,我们仅能对栈顶元素进行操作。

但是你仍然可以使用等号来进行栈和栈之间的赋值。

stack<ll> s1, s2;
s1.push(1);
s1.push(2);
s1.push(3);
s2 = s1;

(2)弹出一个元素 pop()

//{1, 2, 3}
s.pop();//{1, 2}
s.pop();//{1}
s.pop();//{}
s.pop();//run error

因为 stack 也只允许从栈顶弹出元素,所以直接 pop() 即可。但有一点需要格外警惕,如果栈已经为空,那么 pop() 会报错,故而弹出元素之前一定要先判断栈是否为空

(3)获取栈顶元素 top()

//{1, 2, 3}
s.top();//3
s.pop();
s.pop();
s.top();//1
s.pop();
s.top();//run error

和弹出栈顶元素一样,如果栈已经为空,那么 top() 会发生 RE,程序会报错,故而获取栈顶元素之前一定要先判断栈是否为空。

(4)判断栈是否为空empty()

if(s.empty())
    cout << "1" << endl;
else
    cout << "0" << endl;

如果栈为空,empty() 将返回 t r u e true true,否则返回 f a l s e false false

(5)栈的大小 size()

//{1, 2, 3}
cout << s.size() << endl;//3

二、队列

1.简介

队列是 OI 中常用的一种满足一定约束的线性数据结构。队列只允许在其中一端插入,在另一端删除元素,一端被称为队首,另一端被称为队尾。故而队列满足一种“先进先出的原则”。就像在超市购买商品排队结账一样,先进入队伍的先结账离开。

我们可以使用普通的数组来模拟队列,也可以使用 vector,但是 STL 中有更方便和使用方式更明确的 queue

2.定义

#include <queue>

使用 STL 的队列需要首先在代码的开头引入这个头文件。

queue<T> q;

T 表示我们所定义的数组存储数据的类型。它可以是 int, double 这样的基本数据类型,可以是 typedef 之后的代词,也可以是自定义的结构体类型,甚至可以是其他的 STL 类型。

typedef long long ll;
queue<int> a;
queue<double> b;
queue<ll> c;
queue<node> d;
queue<vector<ll> >e;

一开始定义好的队列的长度为 0 0 0,代表一个空的队列。

3.基本操作

(1)插入一个元素 push()

queue<ll> q;//{}
q.push(1);//{1}
q.push(2);//{1, 2}
q.push(3);//{1, 2, 3}

vector 不同的是,queue 无需指定 push_back()。因为 queue 只会从队尾插入。

在队列中无法像 vector 那样对里面的任意元素进行赋值操作(虽然排队的人可以随意离开队伍),我们仅能对队首元素进行操作。

但是你仍然可以使用等号来进行队列和队列之间的赋值。

queue<ll> q1, q2;
q1.push(1);
q1.push(2);
q1.push(3);
q2 = q1;

(2)弹出一个元素 pop()

//{1, 2, 3}
q.pop();//{2, 3}
q.pop();//{3}
q.pop();//{}
q.pop();//run error

因为 queue 也只允许从队首弹出元素,所以直接 pop() 即可。但有一点需要格外警惕,如果队列已经为空,那么 pop() 会报错,故而弹出元素之前一定要先判断队列是否为空

(3)获取队首元素 front()

//{1, 2, 3}
q.front();//1
q.pop();
q.pop();
q.front();//3
q.pop();
q.front();//run error

和弹出队首元素一样,如果队列已经为空,那么 front() 会报错,故而获取队首元素之前一定要先判断队列是否为空。

(4)获取队尾元素 back()

//{}
q.back();//run error
q.push(1);
q.back();//1
q.push(2);
q.back();//2
q.push(3);
q.back();//3

和弹出队首元素一样,如果队列已经为空,那么 back() 会报错,故而获取队尾元素之前一定要先判断队列是否为空。

(5)判断队列是否为空 empty()

if(q.empty())
    cout << "1" << endl;
else
    cout << "0" << endl;

如果栈为空,empty() 将返回 t r u e true true,否则返回 f a l s e false false

(6)队列的大小 size()

//{1,2,3}
cout << q.size() << endl;//3

三、作业

1.栈

B3614 【模板】栈

P1241 括号序列

P1449 后缀表达式

P1944 最长括号匹配

P4387 【深基15.习9】验证栈序列

2.队列

B3616 【模板】队列

P1540 [NOIP2010 提高组] 机器翻译

P1996 约瑟夫问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值