2.1 栈

一、定义

  • 后进先出 (Last In First Out):一种限制访问端口的线性表

  • 主要操作:进栈 (push) 出栈 (pop)

二、实现

1、实现方式

  • 顺序栈 (Array-based Stack)

    • 栈的大小事先固定

    • 存在上溢,下溢问题

  • 链式栈(Linked Stack)

    • 用单链表方式存储,大小可以动态改变

  • 由于所有操作都只需要常数时间,顺序栈和链式栈在时间效率上难分伯仲。链式栈会有额外的空间开销。

  • 实践中,顺序栈的使用更加广泛。

2、代码(顺序栈)

(1)创建
int S[maxn]; //S为顺序栈
int top=-1; //top表示栈顶的位置。初始状态时,栈为空,栈顶为-1。
(2)判断是否为空
bool emp(){
  if (top==-1) return true;
  else return false;
}
(3)进栈
//x进栈
void push(int x){
  ++top;
  S[top]=x;
}
(4)出栈
//弹出栈顶元素,并将其记在x中
bool pop(int x){
  if (emp()) return false; //下溢
  else {
    --top;
    x=S[top+1];
    return true;
  }
}

三、应用

1、表达式求值

计算思路(来自如何用栈实现表达式求值 | 守望的个人博客

  • 使用两个栈,stack0用于存储操作数,stack1用于存储操作符

  • 从左往右扫描,遇到操作数入栈stack0

  • 遇到操作符时,

    • 如果优先级低于或等于栈顶操作符优先级,则从stack0弹出两个元素进行计算,并压入stack0,继续与栈顶操作符的比较优先级

    • 如果遇到操作符高于栈顶操作符优先级,则直接入栈stack1

  • 遇到左括号,直接入栈stack1,遇到右括号,则直接出栈并计算,直到遇到左括号

例题

来源:OpenJudge - 5:等价表达式

描述:判断两个表达式在数学上是否是等价的。

输入 ①第一行:N(1<=N<=20),表示测试数据组数。 接下来每组测试数据包括两行,每行包括一个数学表达式,每个表达式的长度不超过80个字符。输入数据没有空行。 ②一个表达式可能包括: 单个英文字母表示的变量(区分大小写) 数字(只有一位数) 配对的括号 运算符加+、减-、乘* 任意数量的空格或tab(可能出现在表达式中间的任何位置) ③注意:表达式保证是语法正确的,且所有运算符的优先级相同,运算次序从左至右。变量的系数和指数保证不超过16位整数。

输出 对每个测试数据,输出一行:等价则输出“YES”,不等价则输出“NO”。

ac代码:Openjudge 等价表达式-CSDN博客

其他题目

矩阵链乘 (Matrix Chain Multiplication, UVa 442)

2、单调栈

单调栈中,从栈底到栈顶,元素单调递增或递减排列,以单调递减为例,新元素x入栈时,为了维持栈中元素的单调性,需要弹出原来在栈中小于或等于x的元素,再将x入栈。举例来说,我们有以下几个数,需要将它们放入一个单调栈中,并保证栈中元素从栈底到栈顶单调递减。

10
3
7
4
12
2

栈的变化过程如下

                    4
      3        7    7    7               2
10   10   10  10   10   10  10  空  12   12
例题:发型糟糕的一天

来源:OpenJudge - 9:发型糟糕的一天

描述 农夫John 的N(1 ≤ N ≤ 80,000)只奶牛中,有一些也许正在经历发型糟糕的一天。每只奶牛对自己乱糟糟的发型都有自知之明,农夫John想知道所有奶牛能看到其他奶牛头顶的数量之和。 任意奶牛i身高记为 hi (1 ≤ hi ≤ 1,000,000,000),所有奶牛面向东方(本题示意图的右面)依次站成一条线。因此,奶牛i能够看到在它前面的(奶牛i+1,i+2…)所有身高比它低的奶牛,直到被一头不比它低的奶牛挡住。用ci表示奶牛i能够看到头顶的奶牛个数;请计算c1 至cN的和。

输入 第1行:奶牛数N 第2行至N+1行:第i+1行包含一个整数,表示奶牛i的高度

输出 第1行:c1 至cN的累加和

分析:如果把每只哞的高度和前面的哞比较,时间复杂度是O(n^2),会超时,需要找更省时间的办法。这里维护一个单调栈,利用栈顶的位置来计算c1到cN的和。仍以前面的单调栈为例,现在我们只关心在有元素入栈之后栈的状态,前面所写的栈的变化过程可以简化为:

             4
     3   7   7        2
10  10  10  10  12   12

下面看看如何利用栈顶位置计算c1到cN的和。考虑第一只身高为10的哞。为了计算c1,我们需要找到第一只身高超过10的哞,并计算TA和身高为10的哞的距离。在本题中,第一只身高超过10的哞身高为12,TA和身高为10的哞之间有3只哞,身高分别为3,7,4,这三只即第一只哞能看见的哞。无独有偶,我们发现,在上图所示的栈的变化过程中,身高为10的哞在栈中总共待了4=3+1轮。类似的,身高为3的哞看不见其他哞(即看见0只哞),TA在栈中待了1=0+1轮……由此发现,我们用所有哞在栈中待的轮数减去哞的总数,就可以得到c1到cN的和。 于是现在问题转化成如何求所有哞在栈中待的轮数。可以看出,对于每种栈的状态,top+1表示栈中的元素个数,我们只要把上图每种状态中的top+1求和即可。

  • 24
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值