静态栈
食用指南:
对该算法程序编写以及踩坑点很熟悉的同学可以直接跳转到代码模板查看完整代码
只有基础算法的题目会有关于该算法的原理,实现步骤,代码注意点,代码模板,代码误区的讲解
非基础算法的题目侧重题目分析,代码实现,以及必要的代码理解误区
题目描述:
-
实现一个栈,栈初始为空,支持四种操作:
push x – 向栈顶插入一个数 x;
pop – 从栈顶弹出一个数;
empty – 判断栈是否为空;
query – 查询栈顶元素。
现在要对栈进行 M 个操作,其中的每个操作 3 和操作 4 都要输出相应的结果。输入格式
第一行包含整数 M,表示操作次数。
接下来 M 行,每行包含一个操作命令,操作命令为 push x,pop,empty,query 中的一种。输出格式
对于每个 empty 和 query 操作都要输出一个查询结果,每个结果占一行。
其中,empty 操作的查询结果为 YES 或 NO,query 操作的查询结果为一个整数,表示栈顶元素的值。数据范围
1≤M≤100000,
1≤x≤109
所有操作保证合法。输入样例:
10
push 5
query
push 6
pop
query
pop
empty
push 4
query
empty
输出样例:
5
5
YES
4
NO -
题目来源:https://www.acwing.com/problem/content/830/
题目分析:
- 模拟栈
和静态链表一样,能使用数组模拟数据结构,就不使用结构体,省时间省空间
下面就来看看如何使用数组模拟一个栈
算法原理:
相关算法:
静态栈:
1. 存储形式:
- 栈本身:以数组stk[N]存储元素,从stk[1]开始存储便于计数
- 栈顶:以变量int top 记录栈顶元素序号,就像单链表链表头,每次都指向第一个元素
- 初始化:stk[]数组可以不管初始化,top也可以是1可以是0,但是一定要保证从1开始存储
2. 入栈:
const int N = 100010;
int skt[N];
int top = 0;
void push(int x){
//栈也从1计数,先++再赋值,保证每次tt都不为空
skt[++top] = x;
}
3. 出栈:
- 栈顶出栈并返回元素
int pop(){
int tmp = skt[top];
top--;
return tmp;
}
4. 判空:
bool empty(){
return top == 0;
}
5. 取栈顶元素:
- 此处取完后栈顶元素还在栈内
int stacktop(){
return stk[top];
}
代码实现:
- 其实主干已经讲解完成了,下面的代码主要示范如何模仿读指令操作
主要利用的是STL中的string数据结构
int main(){
int n = 0;
cin >>n;
while(n--){
string s;
cin >> s;
if(s == "push")
{
int a;
cin >> a;
push(a);
}
if(s == "pop")
{
pop();
}
if(s == "query")
{
cout << stacktop() << endl;
}
if(s == "empty")
{
cout << (empty() == -1 ? "YES" : "NO") << endl;
}
}
}
代码误区:
1. top能不能初始化为1?
- 可以,
- 入栈:stk[top++] = x;
- 出栈:top -= 2;
- 判空:return top == 0?
- 栈顶元素:return stk[top-1];
2. 栈中元素可否有多个属性?
- 可以,再创建对应属性数组即可,要保证所有属性数组索引统一于top
3. 栈数组可否从stk[0]开始使用?
- 可以,根据题意选择方便的起始索引
本篇感想:
- 单纯说栈这个数据结构也就一句话,先入后出,每次只能对top所指的元素操作
难点在栈的应用,后面的几篇博客会做栈例题 - 焯,距离上一篇博客发布过了3H,加速,不能休息了,今天过30大关
- 看完本篇博客,恭喜已登 《练气境-后期》
后期内容主要有栈,堆,队列,字典树,并查集,五大部分
学完这些之后进入图论,开启 《筑基境》
对dfs bfs不熟悉的同学看这里准备准备:【算法设计】用C++类和队列实现图搜索的广度优先遍历算法
距离登仙境不远了,加油