当前位置: 首页 > article >正文

数据结构与算法——Java实现 45.根据后缀表达式建树

别担心,一切都是最好的安排

                                —— 24.10.22

根据后缀表达式建树

根据一个后缀表达式来构造表达式的树

中缀表达式:(2-1)*3

后缀(逆波兰)表达式:21-3*

表达式的树:

                *

              /    \

            -        3

          /    \    

        2       1 


思路

解决这个问题(首先判断合法性)

从左向右遍历后缀表达式

1.遇到数字则入栈

2.遇到运算符则出栈,建立节点关系,然后再入栈

3.先弹栈的是右孩子,后弹栈的是左孩子

合法性:

先弹栈的是右孩子,后弹栈的是左孩子

验证:根据后缀表达式建的树,进行后序遍历,求得的表达式应该是原来的后缀表达式


代码实现

节点类

由于传入的后缀表达式是字符串,所以将结点类和实现改变一下

    static class TreeNode{
        public String val;
        public TreeNode left;
        public TreeNode right;

        public TreeNode(String val){
            this.val = val;
        }

        public TreeNode(String val, TreeNode left, TreeNode right) {
            this.val = val;
            this.left = left;
            this.right = right;
        }

        @Override
        public String toString() {
            return this.val;
        }
    }

后缀表达式建树

使用栈对后缀表达式从左到右进行遍历,对后缀表达式中的每一个字符进行判断,如果是数字则入栈,如果是字符则将栈中的元素出栈,先出的元素建立在符号的右子树,后出的元素为左子树,然后再将这个字符进行入栈,继续遍历

    public static TreeNode constructExpression(String[] expression) {
        if (expression == null || expression.length == 0) {
            return null;
        }
        LinkedList<TreeNode> stack = new LinkedList<>();
        for (String s : expression) {
            switch (s){
                case "+","-","*","/" -> {
                    TreeNode right = stack.pop();
                    TreeNode left = stack.pop();
                    TreeNode parent = new TreeNode(s);
                    parent.left = left;
                    parent.right = right;
                    stack.push(parent);
                }
                default -> {
                    stack.push(new TreeNode(s));
                }
            }
        }
        return stack.peek();
    }

后序遍历 

根据后缀表达式建的树,进行后序遍历,求得的表达式应该是原来的后缀表达式

反向思考,要想验证出所建立的二叉树,最后将二叉树进行后序遍历,与给出的后缀表达式进行比较,则可以判断是否正确

    public static void post(CreateTreeByExpression.TreeNode node, ArrayList<String> res){
        if (node == null){
            return;
        }
        post(node.left, res);
        post(node.right, res);
        res.add(node.val);
    }

整体代码

package Day16BinaryTree;

import java.util.ArrayList;
import java.util.LinkedList;

public class CreateTreeByExpression {
    static class TreeNode{
        public String val;
        public TreeNode left;
        public TreeNode right;

        public TreeNode(String val){
            this.val = val;
        }

        public TreeNode(String val, TreeNode left, TreeNode right) {
            this.val = val;
            this.left = left;
            this.right = right;
        }

        @Override
        public String toString() {
            return this.val;
        }
    }

    public static void post(CreateTreeByExpression.TreeNode node, ArrayList<String> res){
        if (node == null){
            return;
        }
        post(node.left, res);
        post(node.right, res);
        res.add(node.val);
    }

    public static TreeNode constructExpression(String[] expression) {
        if (expression == null || expression.length == 0) {
            return null;
        }
        LinkedList<TreeNode> stack = new LinkedList<>();
        for (String s : expression) {
            switch (s){
                case "+","-","*","/" -> {
                    TreeNode right = stack.pop();
                    TreeNode left = stack.pop();
                    TreeNode parent = new TreeNode(s);
                    parent.left = left;
                    parent.right = right;
                    stack.push(parent);
                }
                default -> {
                    stack.push(new TreeNode(s));
                }
            }
        }
        return stack.peek();
    }

    public static void main(String[] args) {
        String[] expression = {"2","1","-","3","*"};
        TreeNode root = new CreateTreeByExpression().constructExpression(expression);
        ArrayList<String> res = new ArrayList<>();
        post(root, res);
        System.out.println(res.toString());
    }
}


http://www.kler.cn/news/362474.html

相关文章:

  • 【优选算法】探索双指针之美(一):双指针与单调性的完美邂逅
  • 爬虫基础--requests模块
  • 使用JUC包的AtomicXxxFieldUpdater实现更新的原子性
  • leetcode day3 1+14+15
  • 软件测试与软件缺陷的基础知识
  • C++编程语言:抽象机制:特殊运算符(Bjarne Stroustrup)
  • 在使用new Date()生成时间戳时,发现数据库中 的时间总是多出一秒钟。
  • Android SELinux——neverallow问题处理(十六)
  • 智在未来:人工智能与人类社会的融合
  • 查看centos系统版本
  • 使用 EasyExcel 相邻数据相同时行和列的合并,包括动态表头、数据
  • python装饰器property的使用
  • 详细说明如何使用C++编写A*算法
  • 算法笔记day05
  • 面试总结分享:25道数据库测试题
  • HCIP-HarmonyOS Application Developer 习题(十)
  • 关于风险系统解读最全最专业文章:一篇文章讲透风险,跨学科搞懂风险游戏规则,风险信任风险主观性客观性风险本质人格特质与风险态度技术风险系统风险社会新产品风险
  • Flutter 中的 PopScope 小部件:全面指南
  • 阿里巴巴最新版Spring Security OAuth2.0认证授权笔记开源
  • 拼三角问题
  • 三菱FX5U PLC程序容量设置
  • vue-router钩子中调用ElMessage等样式出错
  • curl,nc和telnet的用法以及其他常用工具(nc代理与重定向)
  • MySQL - Navicat自动备份MySQL数据
  • JVM-编译期处理与Java语法糖
  • 如何在 HarmonyOS NEXT 中使用 @Builder 装饰器优化 UI 组件的复用?