栈
简述栈(Stack)
栈(Stack)是只允许在一端进行插入或删除操作的线性表。
首先栈是一个线性表,其次它只能在一端进行插入和删除(后入先出,先入后出)。
相关术语
栈顶(Top)
线性表允许插入和删除的那一端。
栈底(Bottom)
线性表不允许插入和删除的那一端。
空栈
没有元素的栈。
栈的存储
栈可以用链表存储也可以用数组(顺序表)存储。
顺序表存储
用顺序表存储的栈叫做顺序栈,它需要存储两项数据,一项为数组data,用来存储栈元素。一项为栈顶指针top,用来标记当前栈顶位置。
由于数组是从0开始存储,因此我们将栈空设置为-1。
struct stack{
int data[N]; // 存储栈元素,N为数组长度
int top; // 栈顶指针
}
链表存储
用链表存储的栈叫做链栈,它也要存储两项数据,一项为栈元素data,一项为next指针。与链表相同,也有带头结点和不带头结点两种实现方法。
struct stack{
int val;
stack* next;
}
栈的基本操作(以顺序栈为例)
初始化(init)
初始化一个空栈。
void init(stack* stk) {
stk -> top = -1; // 栈空为-1
}
判断栈空(empty)
如果栈为空返回true,否则返回false
bool empty(stack* stk) {
return stk -> top == -1;
}
入栈(push)
首先判断栈有没有满,如果满了就无法再插入元素了。
然后插入元素。
bool push(stack* stk,int val) {
if(stk -> top == N - 1) // 如果栈满,返回false
return false;
stk -> data[++ stk -> top] = val;
return true; // 成功插入
}
出栈(pop)
首先判断栈是否为空,如果栈为空则无法再删除元素。
bool pop(stack* stk) {
if(empty(stk)) return false;
stk -> top --;
return true; // 成功删除
}
读栈顶元素(top)
首先判断栈是否为空,如果为空则没有栈顶元素可读取。
int top(stack* stk) {
if(empty(stk)) return -1; // return内容可自由选定
return stk -> data[stk -> top];
}
例题
题目描述
实现一个栈,栈初始为空,支持四种操作:
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≤M≤100000
1≤M≤100000,
1
≤
x
≤
1
0
9
1≤x≤10^9
1≤x≤109
所有操作保证合法。
输入样例:
10
push 5
query
push 6
pop
query
pop
empty
push 4
query
empty
输出样例:
5
5
YES
4
NO
解题思路
显然这是一个栈模拟题,只需要将操作函数写入即可。
代码
#include<iostream>
#include<cstring>
using namespace std;
const int N = 1e5 + 10;
int m;
struct stack{
int data[N];
int top;
};
// 初始化
void init(stack* stk){
stk->top = -1;
}
// 判空
bool empty(stack* stk) {
return stk -> top == -1;
}
// 插入
bool push(stack* stk,int val) {
if(stk->top == N - 1) return false;
stk -> data[++ stk->top] = val;
return true;
}
// 删除
bool pop(stack* stk) {
if (empty(stk)) return false;
stk -> top --;
return true;
}
// 获取栈顶元素
int top(stack* stk) {
if(empty(stk)) return -1;
return stk->data[stk->top];
}
int main(){
scanf("%d",&m);
stack *stk = new stack();
init(stk);
while(m --) {
string op;
int x;
cin >> op;
if(op == "push") {
scanf("%d",&x);
push(stk,x);
}
else if(op == "pop") {
pop(stk);
}
else if(op == "empty") {
if(empty(stk)) puts("YES");
else puts("NO");
}
else if(op == "query"){
printf("%d\n",top(stk));
}
}
return 0;
}