单调栈和单调队列详情请看:双指针算法
一、栈
1.栈的概念
栈是限定仅在表尾进行插入和删除操作的线性表。
把允许插入和删除的一端称为栈顶(top),另一端称为栈底 (bottom),不含任何数据元素的栈称为空栈。
- 栈的插入操作,叫作进栈(push),也称压栈、入栈。
- 栈的删除操作,叫作出栈(pop),也有的叫作弹栈。
注:栈称为后进先出的线性表,简称LIFO结构。
栈的作用
栈的引入简化了程序设计的问题,划分了不同关注层次,使得思考范围缩小,更加聚焦于解决的问题核心。在深度优先搜索 bfs 中,用的就是栈的思想。
注:在运算时一定要考虑栈是否为空。
2.静态栈
用静态数组来模拟栈
int st[N], t = 0; // t 表示栈顶,栈从1开始,0 表示栈为空
int push(int k) { // 向栈顶插入元素 k
st[ ++ t] = k;
}
int top() { // 返回栈顶元素
return st[t]; //需要判断栈是否为空
}
void pop() { // 删除栈顶元素
t -- ; //需要判断栈是否为空
}
bool empty() { // 判断栈是否为空
if (t > 0) return true;
else return false;
}
int size() { // 返回栈的长度
return t;
}
void clear(){ //清空栈
t = 0;
}
3.STL 栈 stack
#include<stack> //头文件
template<
class T,
class Container = std::deque<T>
> class stack;
注:Container 为用于存储元素的底层容器类型,可以使用vector , deque, list 这三种STL 容器默认deque。
常用操作:
stack<type> st 定义一个空栈 st
void st.push(k) 将元素 k 放到栈顶
type st.top() 返回栈顶元素,但不删除
void st.pop() 删除栈顶元素
bool st.empty() 判断栈是否为空
int st.size() 返回栈的长度
注:一般很少使用STL中的栈,一般都是自己模拟栈(栈的题目本来就少)。
队列
1.队列的概念
队列是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。
允许插入的一端称为队尾,允许删除的一端称为队头。
注:队列是一种先进先出的线性表,简称FIFO。
栈的作用:可以运用在广度优先搜索 dfs 中。
2.静态队列
用静态数组来模拟队列
int q[N], l = 0, r = -1; // l 表示队头,r表示队尾,队列从0开始
void push(int k) { // 向队尾插入一个数 k
q[ ++ r] = k;
}
int top() { // 返回队头元素
return q[l]; // 需要判断队列是否为空
}
void pop() { // 删除对头元素
l ++ ; // 需要判断队列是否为空
}
bool empty() { // 判断队列是否为空
if (l <= r) return true;
else return false
}
int size() { // 返回队列的长度
return r - l + 1;
}
3.循环队列
目的:减少空间的浪费。
int q[N], l = 0, r = 0; //l表示队头,r表示队尾的后一个位置,a[r-1]是队尾
void push(int k) { // 向队尾插入一个数 k
q[r ++ ] = k;
if (r == N - 1) r = 0;
}
int top() { // 返回队头元素
return q[l]; // 需要判断队列是否为空
}
void pop() { // 删除对头元素
l ++ ;
if (l == N - 1) l = 0; // 需要判断队列是否为空
}
bool empty() { // 判断队列是否为空
if (l != r) return true;
else return false
}
int size() { // 返回队列的长度
return (r - l + N) % N;
}
4.STL 队列 queue
#include<queue> //头文件
template<
class T,
class Container = std::deque<T>
> class queue;
注:容器可以 使用 deque 和 list ,默认使用 deque 作为底层容器。
常用操作:
queue<type> q 定义队列 q
void q.push(k) 将元素放到队尾
type q.front() 返回队首元素,但不删除
type q.back() 返回队尾元素
void q.pop() 删除队首元素
bool q.empty() 判断队列是否为空
int q.size() 返回队列的长度
参考:acwing ,y总