一、栈
1.简介
栈是 OI 中常用的一种满足一定约束的线性数据结构。栈只允许在其中一端插入和删除元素,这一端被称为栈顶,另一端被称为栈底。故而栈满足一种“先进后出的原则”。就像放进收纳盒的书,只有拿出上面的书之后,才能取出下面的书。
我们可以使用普通的数组来模拟栈,也可以使用vector
,但是 STL 中有更方便和使用方式更明确的stack
。
2.定义
#include <stack>
using namespace std;
int main()
{
return 0;
}
使用 STL 的栈需要首先在代码的开头引入这个头文件,并不要忘记using namespace std;
stack<T> s;
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()
会报错,故而获取栈顶元素之前一定要先判断栈是否为空。
(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 表示我们所定义的数组存储数据的类型。它可以是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