news 2026/4/19 19:26:44

【数据结构与算法】栈的中缀转后缀 中缀转前缀

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【数据结构与算法】栈的中缀转后缀 中缀转前缀

👨‍💻 关于作者:会编程的土豆

“不是因为看见希望才坚持,而是坚持了才看见希望。”

你好,我是会编程的土豆,一名热爱后端技术的Java学习者。

📚正在更新中的专栏:

  • 《数据结构与算法》😊😊😊

  • 《leetcode hot 100》🥰🥰🥰🤩🤩🤩

  • 《数据库mysql》

💕作者简介:后端学习者

概念:栈是一种先进后出(LIFO,Last In First Out) 的线性数据结构,类比生活中叠盘子——最后叠上去的盘子先被拿走,最下面的盘子最后取出,核心操作仅围绕“入栈”和“出栈”展开。和队列类似。

只允许在栈顶出入和删除;

例:1,2,3,4四个数字按顺序进栈,则可能的出栈顺序是?

A,3,1,4,2 B.2,4,1,3 C.1,3,2,4 D.3,4,1,2

答:C;

A:进1,2,3,出3,此时栈为1,2;此时只能先出2再出1 ,所以1不可能在2前面;

B:进1,2,出2,再进3,4,出4,此时栈为1,3,只能先出3,

C:进1,出1,进2,3出3,此时栈为2,出2,进4出4,可

D:进1,2,3出3,进4出4,此时栈为1,2;只能先出2

1.相关操作概念

1、入栈(Push):将一个元素添加到栈顶,使其成为新的栈顶元素。入栈操作需要将元素放到栈顶位置,并更新栈顶指针。

2、出栈(Pop):将栈顶元素删除,并返回该元素的值。出栈操作需要将栈顶元素删除,并更新栈顶指针。

3、判空(Empty):判断栈是否为空,即栈中是否没有任何元素。

作用:检查栈内是否有元素

如果栈中没有任何元素,返回 true (表示“空”);

如果栈中存在元素,返回 false (表示“非空”)。

4、获取栈顶元素(Top):获取栈顶元素的值,但不删除该元素。

5、销毁栈(DestroyStack):销毁栈,并释放栈占用的存储空间。

2.算术表达式的前中后缀表达式

对于平时的四则运算表达式,也称作中缀表达式,存在先乘除,后加减,从左到右,先括号内后括号外的运算法则,使得计算机在计算四则运算时非常复杂,因此出现了后缀表达式。

中转后是从左到右保证栈顶的符号优先级最高,遇到相等级别的也要排除栈里的,就是说要保证栈顶的元素是最新的最大级别的运算符号;相同要弹出

中转钱是从右往左走,也是保证栈顶是最大优先级别的,但是遇到相同级别的不会弹出;

特性中缀 → 后缀中缀 → 前缀
扫描方向从左到右从右到左
操作数输出直接输出直接输出(但顺序会反转)
栈的优先级规则栈顶优先级最高栈顶优先级最高(但比较时用原优先级)
括号处理( 入栈,) 弹到 () 入栈,( 弹到 )(括号互换)
最终结果直接得到需要反转
特性中缀 → 后缀中缀 → 前缀
扫描方向从左到右从右到左
栈的目标保证栈顶是当前最高优先级保证栈顶是当前最高优先级
相同优先级处理弹出(先来的先走)不弹出(后来的直接进)
括号处理( 入栈,) 弹到 () 入栈,( 弹到 )
最后操作直接输出反转输出

后缀表达式

后缀表达式中所有的字符都出现在运算数字后面。

中缀表达式转后缀表达式:从左至右遍历中缀表达式,遇到数字则输出,遇到字符就比较其与栈顶符号的优先级,是右括号或优先级小于等于栈顶符号则栈顶元素依次出栈并输出,并将当前符号进栈,一直到所有字符都输出完成。

后缀表达式的运算:从左至右遍历后缀表达式,遇到数字则入栈,遇到运算符则将处于栈顶的两个数字出栈进行运算,运算结果入栈,直到计算结束。

前缀表达式

前缀表达式的运算:从右至左遍历前缀表达式,遇到数字则入栈,遇到运算符则将处于栈顶的两个数字出栈进行运算,运算结果入栈,直到计算结束。

中缀表达式转前缀表达式:从右至左遍历中缀表达式,遇到数字便输出,遇到运算符则比较其与栈顶符号的优先级,若是左括号或优先级小于栈顶符号则输出,并将当前符号进栈,一直到所有字符输出结束。

简易版转化方法

将中缀表达式(a+b)*c+d-(e+g)*h转换为前缀表达式

法 1: 加括号法/直接法

注意每一个配对的括号内都包含两个子表达式和一个运算符

((((a+b)*c)+d)-((e+g)*h))

随后将同一括号内的运算符提取到括号前

-(+(*(+(ab)c)d)*(+(eg)h))

随后将括号去除得到: -+*+abcd*+egh即为前缀表达式

变体:

将该中缀表达式转换为后缀表达式

使用加括号法得到((((ab)+c)*d)+((eg)+h)*)-

去掉括号从而得到ab+c*d+eg+h*-

例:

栈与中缀转后缀(逆波兰表达式)详解

在计算机科学中,表达式求值是一个非常经典的问题,而是解决中缀表达式转后缀表达式(逆波兰表达式)的利器。本文详细讲解这一过程,并附带完整 C++ 示例代码。


一、问题背景

  • 输入:中缀表达式(如3+4*2/(1-5)^2^3

  • 输出:后缀表达式(如3 4 2 * 1 5 - 2 3 ^ ^ / +

目的:后缀表达式便于计算机直接计算,因为它不需要括号即可确定运算顺序。


二、栈的作用

核心思想:

  • 栈用于保存运算符

  • 遇到操作数直接输出

  • 遇到运算符比较优先级决定是否弹栈

  • 遇到括号做特殊处理


三、算法步骤

  1. 初始化一个空栈ops保存运算符,空字符串output保存后缀表达式

  2. 从左到右遍历中缀表达式的每个字符:

    • 如果是操作数 → 直接输出到output

    • 如果是左括号(→ 入栈

    • 如果是右括号)→ 弹出栈顶运算符直到遇到左括号

    • 如果是运算符:

      • 栈非空且栈顶运算符优先级高(或相等且左结合) → 弹栈输出

      • 当前运算符入栈

  3. 遍历结束后,将栈中剩余运算符依次弹出输出


四、运算符优先级与结合性

  • 优先级:

    • +,-→ 1

    • *,/→ 2

    • ^→ 3

  • 结合性:

    • +,-,*,/→ 左结合

    • ^→ 右结合

结合性影响栈中运算符弹出顺序。例如,2^3^2要从右向左结合。


五、完整 C++ 代码示例

#include <iostream> #include <string> #include <stack> #include <cctype> using namespace std; // 获取运算符优先级 int priority(char op) { switch(op) { case '+': return 1; case '-': return 1; case '*': return 2; case '/': return 2; case '^': return 3; default: return 0; } } // 判断是否为右结合运算符 bool isRightAssoc(char op) { return op == '^'; } int main() { string s; cin >> s; stack<char> ops; string output = ""; for (int i = 0; i < s.length(); i++) { char c = s[i]; if (isdigit(c)) { output += c; output += ' '; } else if (c == '(') { ops.push(c); } else if (c == ')') { while (!ops.empty() && ops.top() != '(') { output += ops.top(); output += ' '; ops.pop(); } if (!ops.empty()) ops.pop(); } else { while (!ops.empty() && ops.top() != '(') { if (isRightAssoc(c)) { if (priority(c) < priority(ops.top())) { output += ops.top(); output += ' '; ops.pop(); } else break; } else { if (priority(c) <= priority(ops.top())) { output += ops.top(); output += ' '; ops.pop(); } else break; } } ops.push(c); } } while (!ops.empty()) { output += ops.top(); output += ' '; ops.pop(); } if (!output.empty()) output.pop_back(); cout << output << endl; return 0; }

六、执行示例

输入:

3+4*2/(1-5)^2^3

输出:

3 4 2 * 1 5 - 2 3 ^ ^ / +
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/19 19:25:46

程序员面试:OpenClaw生成面试题、模拟面试,高效备战面试

程序员面试&#xff1a;OpenClaw生成面试题、模拟面试&#xff0c;高效备战面试引言在当今竞争激烈的科技行业中&#xff0c;程序员面试已成为求职过程中的关键环节。无论是应届毕业生还是资深开发者&#xff0c;面对算法题、系统设计题和行为问题&#xff0c;都可能感到压力重…

作者头像 李华
网站建设 2026/4/19 19:19:30

GitHub中文界面快速配置指南:告别语言障碍,专注代码开发

GitHub中文界面快速配置指南&#xff1a;告别语言障碍&#xff0c;专注代码开发 【免费下载链接】github-hans [废弃] {官方中文马上就来了} GitHub 汉化插件&#xff0c;GitHub 中文化界面。 (GitHub Translation To Chinese) 项目地址: https://gitcode.com/gh_mirrors/gi/…

作者头像 李华
网站建设 2026/4/19 19:16:32

专业PCB逆向分析利器:OpenBoardView深度实战指南

专业PCB逆向分析利器&#xff1a;OpenBoardView深度实战指南 【免费下载链接】OpenBoardView View .brd files 项目地址: https://gitcode.com/gh_mirrors/op/OpenBoardView OpenBoardView是一款专业的开源PCB文件查看器&#xff0c;专注于.brd电路板文件的逆向分析和可…

作者头像 李华
网站建设 2026/4/19 19:16:29

STM32实战指南:HAL库驱动FatFS文件系统移植与优化

1. FatFS文件系统基础认知 第一次接触FatFS时&#xff0c;我和大多数嵌入式开发者一样充满疑惑&#xff1a;为什么要在资源有限的STM32上跑文件系统&#xff1f;直到某次项目需要记录设备运行日志到SD卡&#xff0c;我才真正体会到它的价值。想象一下&#xff0c;如果没有文件系…

作者头像 李华
网站建设 2026/4/19 19:15:33

OrthoFinder结果深度挖掘:从Orthogroup到功能注释与进化分析的完整流程

OrthoFinder结果深度挖掘&#xff1a;从Orthogroup到功能注释与进化分析的完整流程 当你第一次运行OrthoFinder并看到输出目录里那些密密麻麻的文件时&#xff0c;可能会感到既兴奋又困惑。这个强大的工具已经帮你完成了基因家族聚类、物种树构建等基础工作&#xff0c;但真正的…

作者头像 李华
网站建设 2026/4/19 19:15:31

TShock 5.1.2 配置精解:从安全防护到游戏体验的全方位调校指南

1. TShock 5.1.2 配置文件基础认知 初次接触TShock服务器的朋友&#xff0c;面对config.json里密密麻麻的参数难免会感到头疼。其实这个配置文件就像乐高积木的说明书&#xff0c;掌握关键模块就能搭建出理想的游戏环境。我刚开始管理服务器时&#xff0c;花了整整三天才摸清门…

作者头像 李华