一、非递归先序遍历二叉树
算法的基本思想:
- 将根节点压入栈
- 取出栈顶元素,若右子树不为空,右子树入栈,若左子树不为空,左子树入栈
- 执行步骤2直到栈为空
1 | public class Traversal { |
二、表达式求值
任何一个表达式都是由操作数(operand)、运算符(operator)和界限符(delimiter)构成,我们把运算符和界限符统称为算符,它们构成的集合定义为OP,算符间的优先级关系如下表所示:
+ | - | * | / | ( | ) | # | |
---|---|---|---|---|---|---|---|
+ | > | > | < | < | < | > | > |
- | > | > | < | < | < | > | > |
* | > | > | > | > | < | > | > |
/ | > | > | > | > | < | > | > |
( | < | < | < | < | < | = | |
) | > | > | > | > | > | > | |
# | < | < | < | < | < | = |
“(”和”)”的关系为相等,表示当左右括号相遇时候,括号内的运算已经完成,同理,当两个”#”相遇时表示整个表达式求值完毕。”)”与”(”、”#”与”)”和”(”与”#”之间无对应优先关系,因为其不合法。
定义两个栈,其中一个存放运算符,另一个存放操作数或计算的结果。
算法基本思想为:
- 初始化操作数栈为空栈,表达式起始符”#”为运算符栈的栈底元素;
- 依次读入表达式的每个字符,若为操作数则进入操作数栈,如是运算符则和运算符栈的栈定元素进行比较,这里有三种情况:
- 栈顶元素优先权低:直接将操作符入栈,读入下一个字符
- 两操作符优先权相等:脱括号,读入下一个字符
- 栈顶元素优先权高:腿栈计算结果,并将计算结果入操作数栈
- 继续读入直到表达式求值完毕,即运算符栈的栈顶元素和当前读入的字符均为”#”
代码实现如下:
1 | public class Express { |