10.stack和queue

一、栈

1.简介

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

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

2.定义

#include <stack>
using namespace std;
int main()
{
    return 0;
}

使用 STL 的栈需要首先在代码的开头引入这个头文件,并不要忘记using namespace std;

stack<T> s;

T 表示我们所定义的数组存储数据的类型。它可以是intdouble这样的基本数据类型,可以是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()会报错,故而获取栈顶元素之前一定要先判断栈是否为空。

(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>
using namespace std;
int main()
{
    return 0;
}

使用 STL 的队列需要首先在代码的开头引入这个头文件,并不要忘记using namespace std;

queue<T> q;

T 表示我们所定义的数组存储数据的类型。它可以是intdouble这样的基本数据类型,可以是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、付费专栏及课程。

余额充值