据结构与算法之美 - 04 栈

本文介绍了栈的基本概念,包括后进先出的性质,并详细讲述了如何通过顺序栈和链式栈来实现。讨论了栈在函数调用、表达式求值、括号匹配以及浏览器前进、后退功能中的应用,提供了具体的实现思路和步骤。

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

栈的定义

在这里插入图片描述

  • 后进者先出,先进者后出,这就是典型的栈结构!!!
  • 当某个数据集合只涉及在一端插入和删除数据,并且满足后进先出、先进后出的特性,我们选择栈这种数据结构!!!

如何实现一个栈

  • 顺序栈

用数组来实现的

  • 链式栈

用链表实现的

栈的应用

支持动态扩容的顺序栈

  • 底层依赖一个支持动态扩容的数组
  • 当数组满了以后,就申请一个更大的数组,将原来的数据搬移到新数组中
    在这里插入图片描述

栈在函数调用中的应用

int main() {
   int a = 1; 
   int ret = 0;
   int res = 0;
   ret = add(3, 5);
   res = a + ret;
   printf("%d", res);
   reuturn 0;
}

int add(int x, int y) {
   int sum = 0;
   sum = x + y;
   return sum;
}

上面代码对应的栈的操作步骤为:
在这里插入图片描述

栈在表达式求值的应用

如何让计算机实现34 + 13 * 9 + 44 - 12 / 3呢?

  • 通过两个栈来实现
  • 其中一个保存操作数的栈
  • 另外一个保存运算符的栈
  • 从左到右遍历数据,当遇到数字,直接压入操作数栈;当遇到运算符,与运算符栈的栈顶元素进行比较
  • 如果比运算符栈顶元素的优先级高,就将当前运算符入栈;如果比运算符栈顶元素优先级低或者相同,则从运算符栈中取出栈顶元素,从操作数栈的栈顶取2个操作数,然后进行计算,再把计算完的结果压入操作数栈,继续比较。
    在这里插入图片描述

栈在括号匹配中的应用

我们假设表达式中只包含三种括号,圆括号 ()、方括号[]和花括号{},并且它们可以任意嵌套。比如,{[] ()[{}]}或[{()}([])]等都为合法格式,而{[}()]或[({)]为不合法的格式。那我现在给你一个包含三种括号的表达式字符串,如何检查它是否合法呢?

  • 遍历字符串
  • 遇到左括号则将括号压入栈,当遇到右括号,则将左括号栈的栈顶元素 与 当前元素进行匹配。
  • 若完成匹配,栈顶元素出栈,继续向下扫描。若不匹配,则退出程序,返回不合法
  • 扫描完毕后,返回合法

如何通过栈实现浏览器的前进、后退功能?

  • 使用两个栈来实现X 与 Y来实现
  • 分别针对四种情况进行分析

你顺序查看了 a,b,c 三个页面,我们就依次把 a,b,c 压入栈,这个时候,两个栈的数据就是这个样子:
在这里插入图片描述

当你通过浏览器的后退按钮,从页面 c 后退到页面 a 之后,我们就依次把 c 和 b 从栈 X 中弹出,并且依次放入到栈 Y
在这里插入图片描述

这个时候你又想看页面 b,于是你又点击前进按钮回到 b 页面,我们就把 b 再从栈 Y 中出栈,放入栈 X 中
在这里插入图片描述

你通过页面 b 又跳转到新的页面 d 了,页面 c 就无法再通过前进、后退按钮重复查看了,所以需要清空栈 Y
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值