一、栈
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