数据结构与算法学习笔记三--栈

本文详细介绍了栈这种数据结构,包括栈的应用场景如子程序调用、递归处理、表达式转换和求值,以及如何使用数组实现栈。通过实例分析了栈在计算器实现、前缀和后缀表达式求值中的作用,并阐述了中缀表达式转后缀表达式的思路步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. 栈的英文为(stack)
  2. 栈是一个先入后出(filo)的有序链表
  3. 栈是限制线性表中元素的插入和删除只能在线性表的同一端进行的一种特殊线性表。允许插入和删除的一端,为变化的一端,称为栈顶 (Top),另一端为固定的一端,称为栈底 (Bottom)
  4. 根据栈的定义可知,最先放入栈中元素在栈底,最后放入的元素在栈顶,而删除元素刚好相反,最后放入的元素最先删除,最先放入的元素最后删除。
  5. 出栈(pop),入栈(push)

1.栈的应用场景

  1. 子程序的调用:在跳往子程序前,会先将下一个指令的地址存到堆栈中,直到子程序执行完后再将地址取出,以回到原来的程序中。
  2. 处理递归调用:和子程序的调用类似,只是除了存储下一个指令的地址外,也将参数、区域变量等数据存入堆栈中。
  3. 表达式的转换【中缀表达式转后缀表达式】与求值(实际解决)。
  4. 二叉树的遍历
  5. 图形的深度优化(depth-first)搜索法

2. 使用数组 实现 栈 的思路分析

  1. 使用数组来模拟栈
  2. 定义一个 top 来表示栈顶,初始化为 -1
  3. 入栈的操作,当有数据加入到栈时,top++;stack[top] = data;
  4. 出栈的操作,int value = stack[top];top–,return value;

3. 使用栈实现计算器的思路分析

在这里插入图片描述

  1. 通过一个 index 值(索引),来遍历我们的表达式
  2. 如果我们发现是一个数字,就直接入数栈
  3. 如果发现扫描到的是一个符号,就分如下情况:
    3.1 如果发现当前的符号栈为空,就直接入栈
    3.2 如果符号栈有操作符,就进行比较,如果当前的操作符的优先级小于或者等于栈中的操作符,就需要从数栈中pop出两个数,再从符号栈中pop出一个符号,进行运算,将得到的结果入数栈,然后将当前的操作符入符号栈.如果当前的操作符的优先级大于栈中的操作符,就直接入符号栈
  4. 当表达式扫描完毕,就顺序的从数栈和符号栈中pop出相应的数和符号,并运行.
  5. 最后在数栈中只有一个数字,就是表达式的结果.

4. 前缀表达式的计算机求值

从右至左扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(栈顶元素 和 次顶元素),并将结果入栈;重复上述过程直到表达式最左端,最后运算得出的值即为表达式的结果.

ps: (3+4)x5-6 对应的前缀表达式就是 - x + 3 4 5 6,针对前缀表达式求值步骤如下:
1)从右至左扫描,将6,5,4,3压入堆栈.
2) 遇到 + 运算符,因此弹出3和4(3为栈顶元素,4为次顶元素),计算出3 + 4的值,得7,再将7入栈.
3) 接下来是 X 运算符,因此弹出 7 和 5,计算出 7 X 5= 35,将35 入栈
4) 最后是 -运算符,计算出 35 -6 的值,即 29,由此得出最终结果.

5. 后缀表达式的计算机求值

  1. 后缀表达式又称为 逆波兰表达式,与前缀表达式相似,只是运算符位于操作数之后.
  2. 举例说明: (3 + 4) x 5 -6 对应的后缀表达式就是 3 4 + 5 * 6 -
  3. 再比如:

在这里插入图片描述从左至右扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(次顶元素 和 栈顶元素),并将结果入栈;重复上述过程直到表达式最右端,最后运算得出的值即为表达式的结果

例如:(3 + 4) x 5 - 6 对应的后缀表达式就是 3 4 + 5 X 6 - ,针对后缀表达式求值步骤如下:

  1. 从左至右扫描,将3 和 4 压入堆栈;
  2. 遇到 + 运算符,因此 弹出 4 和 3(4 为栈顶元素,3 为次顶元素),计算出3 + 4的值,得 7,再将 7 入栈.
  3. 将 5 入栈;
  4. 接下来就是 X 运算符,因此弹出 5 和 7,计算出 7 x 5 = 35,将35入栈;
  5. 将6入栈
  6. 最后是 - 运算符 ,计算出 35-6 的值,即29,由此得出最终结果.

6. 中缀表达式 转 后缀表达式的思路分析步骤

  1. 初始化两个栈:运算符栈 s1 和 存储中间结果的栈 s2;
  2. 从左至右扫描中缀表达式;
  3. 遇到操作数时,将其压s2;
  4. 遇到运算符时,比较其与s1栈顶运算符的优先级;
    1)如果s1为空,或栈顶运算符为左括号"(",则直接将此运算符入栈;
    2)否则,若优先级比栈顶运算符的高,也将运算符压入 s1;
    3)否则,将 s1 栈顶的运算符弹出并压入s2中,再次转到 4.1 与s1中新的栈顶运算符相比较;
  5. 遇到括号时:
    1)如果是左括号"则直接压入s1"
    2)如果是右括号")",则依次弹出s1栈顶的运算符,并压入s2,直到遇到左括号为止,此时将这一对括号丢弃
    重复步骤 2 至 5,直到表达式的最右边
    将s1中剩余的运算符依次弹出并压入s2
    依次弹出s2中的元素并输出,结果的逆序即为中缀表达式对应的后缀表达式.
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值