java语言实现由前缀算数表达式生成二叉树并赋值计算

几个月前数据结构的课设,抽到了一个比较简单的题目。想着用java语言来实现一下(学的时候是C语言版的数据结构)。毕竟在java项目中,万物皆可对象化,一个类型的数据创建为一个对象,其他函数可以来调用对象实例化是非常香的,所以我打算用java语言来完成本次课设。Java语言来写一个数据结构项目是很吃香的,毕竟java作为一个成熟的高级语言,它里面封装好了许多可以直接用的非常简便的函数,甚至还有封装好的数据结构比如“栈”,在java里我只需要Stack stack = new Stack;就可以直接生成的一个栈。
没想到网上找不到任何能参考的代码。java语言没有指针把我给难倒了,毕竟我所学的数据结构大量用到了指针功能,最终一个多星期还是写出来了,至于指针我调用了大量的递归,导致代码的可读性和执行效率降了一大截。后来了解了可以用引用类来替代指针(属实是当时java没学好)。为了让老师能看懂代码做了流程图来解释代码。
在这里插入图片描述
具体代码如下

  • 先创建目录tree
  • 创建一个名为Node的java.class文件来建立叶子结点的类,里面有三个成员变量,数据域、左孩子、右孩子。并自动生成了所有成员变量的set和get函数。
    Node.java
package tree;

public class Node {
    Object data = null;//数据
    Node left;//左节点
    Node right = null;//右节点

    public Node(){
    }

    public Node(Object data) {
        super();
        this.data = data;
    }

    public Object getData() {
        return data;
    }
    
    public void setData(Object data) {
        this.data = data;
    }
    
    public Node getLeft() {
        return left;
    }
    
    public void setLeft(Node left) {
        this.left = left;
    }
    
    public Node getRight() {
        return right;
    }
    
    public void setRight(Node right) {
        this.right = right;
    }
    
}
  • 创建二叉树的类,在里面把各种操作都写成了成员方法。
    towtree.java
package tree;

import javax.script.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
import java.util.Stack;

public class towtree<E> {
    private Node root;// 根节点
    private String result = "";// 储存后缀表达式
    Stack<Node> list = new Stack<Node>();// 生成树栈
    Stack<Double>stack = new Stack<Double>();// 计算结果栈

    /*
    * 生成二叉树函数
    * */

    public void add(String str) {
        String[] sarray = str.split("");
        Node node = new Node();
        if (sarray.length == 1) {
            String key = sarray[0];
            root = new Node();
            root.setData(key);
        }
        else {
//            debugcreattree(0,sarray,node);
            creattree(0,sarray,node);
        }

    }

    // 让根节点等于最后一个节点
    public void creattree(int i,String[] str,Node node) {
        String key = str[i];
        char ch = key.charAt(0);
        if ((ch >= 'A' && ch <= 'Z')||(ch >= 'a' && ch <= 'z')||(ch >= '0' && ch <= '9')) {// 如果是字母或数字
            if (node.getData() == null) {                                                  // 进入判断字母或数字语句
                node.setData(key);                                                         // 进入赋值语句
                Node point = list.pop();                                                   // 进入出栈语句
                if (point.getRight() == null ) {                                           // 进入右子树不存在并初始化右子树语句
                    Node node1 = new Node();
                    point.setRight(node1);
                    list.push(point);                                                      // 进入入栈语句
                    int j = i + 1;
                    if (j == str.length)
                        return;
                    creattree(j,str,point.getRight());
                }
                else {                                                                      // 进入右子树存在出栈语句
                    list.push(point);                                                       // 进入入栈语句
                    while (true) {
                        Node pop = list.pop();                                              // pop进入出栈语句
                        if (list.isEmpty())break;
                        Node top = list.pop();                                              // top进入出栈语句
                        if (top.getRight() == null){                                        // 进入右子树为空语句
                            int j = i + 1;
                            if (j == str.length) return;
                            if (top.getLeft().getData() == null ) {                         // 顶栈左子树未赋值并赋值pop语句
                                top.setLeft(pop);
                                list.push(top);                                             // top进入入栈语句
                                creattree(j,str,top.getLeft());
                                break;
                            }
                            creattree(j,str,top.getRight());
                            break;
                        }
                        else if (top.getRight().getData() == null) {
                            if (top.getLeft().getData() == null ) {                         // 进入顶栈左子树未赋值并赋值pop语句
                                top.setLeft(pop);
                                list.push(top);                                             // top进入入栈语句
                                int j = i + 1;
                                if (j == str.length) return;
                                creattree(j,str,top.getRight());
                                break;
                            }else {                                                         // 进入顶栈右子树存在未赋值并赋值pop语句
                                top.setRight(pop);
                                list.push(top);                                             // top进入入栈语句
                                }
                            if (list.isEmpty())break;
                            }
                        }
                    }
                }
        } else {                                                                            // 如果是运算符
            if (i == 0) {
                node.setData(key);
                root = node;
                Node node1 = new Node();
                node.setLeft(node1);
                list.push(node);                                                            // 进入入栈语句
                creattree(1,str,node.getLeft());
            } else {
                Node point = list.pop();                                                    // 进入出栈语句
                if (point.getRight() == null ) {
                    Node node1 = new Node();
                    point.setRight(node1);
                    list.push(point);                                                       // 进入入栈语句
                }else {
                    list.push(point);                                                       // 进入入栈语句
                }
                Node node1 = new Node();
                node1.setData(key);
                int j = i + 1;
                if (j == str.length) return;
                Node node2 = new Node();
                node1.setLeft(node2);
                list.push(node1);                                                           // 进入入栈语句
                creattree(j,str,node1.getLeft());
            }
        }
    }

    /*
    * 调试生成二叉树函数
    * */
    public void debugcreattree(int i,String[] str,Node node) {
        String key = str[i];
        char ch = key.charAt(0);
        if ((ch >= 'A' && ch <= 'Z')||(ch >= 'a' && ch <= 'z')||(ch >= '0' && ch <= '9')) {
            if (node.getData() == null) {
                node.setData(key);
                System.out.println(key+"进入赋值语句");
                Node point = list.pop();
                System.out.println(point.getData().toString()+"进入出栈语句");
                if (point.getRight() == null ) {
                    System.out.println(point.getData().toString()+"进入右子树不存在并初始化右子树语句");
                    Node node1 = new Node();
                    point.setRight(node1);
                    list.push(point);
                    System.out.println(point.getData().toString()+"进入入栈语句");
                    int j = i + 1;
                    if (j == str.length)
                        return;
                    debugcreattree(j,str,point.getRight());
                }
                else {
                    list.push(point);
                    while (true) {
                        Node pop = list.pop();
                        System.out.println(pop.getData().toString()+"出栈");
                        if (list.isEmpty())break;
                        Node top = list.pop();
                        System.out.println(top.getData().toString()+"出栈");
                        System.out.println("pop="+pop.getData().toString()+"top="+top.getData().toString());
                        System.out.println("top.getRight = " + top.getRight());
                        if (top.getRight() == null){
                            System.out.println(top.getData().toString()+"进入右子树不存在并初始化右子树语句");
                            int j = i + 1;
                            if (j == str.length) return;
                            if (top.getLeft().getData() == null ) {
                                System.out.println(key+"进入顶栈左子树未赋值并赋值pop语句");
                                top.setLeft(pop);
                                list.push(top);
                                System.out.println(top.getData().toString()+"入栈");
                                debugcreattree(j,str,top.getLeft());
                                break;
                            }
                            debugcreattree(j,str,top.getRight());
                            break;
                        }
                        else if (top.getRight().getData() == null) {
                            if (top.getLeft().getData() == null ) {
                                System.out.println(key+"进入顶栈左子树未赋值并赋值pop语句");
                                top.setLeft(pop);
                                list.push(top);
                                System.out.println(top.getData().toString()+"入栈");
                                int j = i + 1;
                                if (j == str.length) return;
                                debugcreattree(j,str,top.getRight());
                                break;
                            }else {
                                System.out.println(key+"进入顶栈右子树存在未赋值并赋值pop语句");
                                top.setRight(pop);
                                list.push(top);
                                System.out.println(top.getData().toString()+"入栈");
                            }
                            if (list.isEmpty())break;
                        }
                    }
                }
            }
        } else {//如果是运算符
            if (i == 0) {
                node.setData(key);
                root = node;
                Node node1 = new Node();
                node.setLeft(node1);
                list.push(node);
                System.out.println(key+"进入入栈语句");
                debugcreattree(1,str,node.getLeft());
            } else {
                Node point = list.pop();
                System.out.println(point.getData().toString()+"进入出栈语句");
                if (point.getRight() == null ) {
                    System.out.println(point.getData().toString()+"进入右子树不存在并初始化右子树语句");
                    Node node1 = new Node();
                    point.setRight(node1);
                    list.push(point);
                    System.out.println(point.getData().toString()+"进入入栈语句");
                }else {
                    list.push(point);
                    System.out.println(point.getData().toString()+"进入入栈语句");
                }
                Node node1 = new Node();
                node1.setData(key);
                list.push(node1);
                System.out.println(key+"进入入栈语句");
                int j = i + 1;
                if (j == str.length) return;
                Node node2 = new Node();
                node1.setLeft(node2);
                debugcreattree(j,str,node1.getLeft());
            }
        }
    }

    /**
     * 递归   中序遍历
     */
    public void output() {
        if (root == null)
        System.out.println("请先执行步骤1");
        else output(root);
    }
    
    public void output(Node node) {

        if (node.getLeft() != null) {
            System.out.print("(");
            output(node.getLeft());
        }
        System.out.print(node.getData());
        if (node.getRight() != null) {
            output(node.getRight());
            System.out.print(")");
        }
    }

    /**
    * 查找元素并赋值
    * */
    public void assign(String v,String c) {
        if(root == null)
            System.out.println("请先执行步骤1");
        else {
            assign(v,c,root);
            System.out.println("赋值后表达式为:");
            output(root);
            System.out.println();
        }
    }
    
    public void assign(String v,String c,Node node) {// 中序遍历二叉树遇到所寻字母后进行赋值
        if (node.getLeft() != null) {
            assign(v,c,node.getLeft());
        }
        if(node.getData().toString().equals(v)) {
            node.setData(c);
            return;
        }
        if (node.getRight() != null) {
            assign(v,c,node.getRight());
        }
    }

    /**
    * 返回赋值后的后序表达式并计算
    * */
    public void backtoresult(){
        backtoresult(root);
        if (result == "")
            System.out.println("请先执行步骤1");
        else {
            for (int i = 0; i < result.length(); i++) {
                char key = result.charAt(i);
                if (key >= '0' && key <= '9')// 如果是数字就入栈
                    stack.push(Double.parseDouble(String.valueOf(key)));
                else {
                    if (stack.size() > 1 ) {// 如果是运算符就取两个顶栈元素进行计算并把结果入栈
                        Double pop = stack.pop();
                        Double top = stack.pop();// 注意这里左边是top,右边是pop如-91=>91-左边是9-右边1
                        Double s =  jisuan(top,pop,String.valueOf(key));
                        stack.push(s);
                    }
                }
            }
            Double jisuan = stack.pop();
            System.out.println(jisuan);
            result = "";
        }
    }

    /**
    * 构造出后缀表达式result
    * */
    public void backtoresult(Node node) {
        if (node.getLeft() != null) {
            backtoresult(node.getLeft());
        }
        if (node.getRight() != null) {
            backtoresult(node.getRight());
        }
        String key = node.getData().toString();
        char ch = key.charAt(0);
        if ((ch >= 'A' && ch <= 'Z')||(ch >= 'a' && ch <= 'z')){
            result += '0';
        } else result += node.getData().toString();
    }

    /**
    * 计算函数
    * */
    public double jisuan(double a, double b, String f) {
        switch (f) {
            case "*":
                return a * b;
            case "/":
                if(b==0){
                    System.out.println("除数为0异常返回计算值0,计算值可能出现错误");
                    return 0;
                }
                else return a / b;
            case "+":
                return a + b;
            case "-":
                return a - b;
            case "^": {
                double sum = 1;
                for (int i = 0; i < b; i++) {
                    sum *= a;
                }
                return sum;
            }
        }
        return 0;
    }

    /**
    * 拼接表达式函数
    * */
    public void compound (String p,String e1,String e2){
        Node newroot = new Node();
        newroot.setData(p);
        Node left;
        Node right;
        Node node1 = new Node();
        Node node2 = new Node();
        String[] sarray1 = e1.split("");
        String[] sarray2 = e2.split("");
        root = null;
        creattree(0,sarray1,node1);
        left = root;
        newroot.setLeft(left);
        root = null;
        creattree(0,sarray2,node2);
        right = root;
        newroot.setRight(right);
        output(newroot);
    }
}
  • 建一个主类来实现菜单页面,并实例化二叉树类,在主方法里调用二叉树类的成员方法来实现各个基本功能。
    twochatree.java
package tree;
import java.util.InputMismatchException;
import java.util.Scanner;

public class towchatree{
    private static towtree tt = new towtree();
    private static int chance = 1;
    private String E;
    private String result = "";

    public static void ReadExpre(String exp) {
        tt.add(exp);
    }

    public static void WriteExpre() {
        tt.output();;
        System.out.println("");
    }

    public static void Assign(String v,String c) {
        tt.assign(v,c);
    }

    public static void Value() {
        tt.backtoresult();
    }

    public static void CompoundExpr(String p,String e1,String e2) {
        tt.compound(p, e1, e2);
    }

    public static void main(String[] args) {
        String expression = "";
        for (int i = 0; i < 1000; i++) {
            System.out.println("算术表达式与二叉树程序 请选择你要进行的操作");
            System.out.println("以字符序列的形式输入语法正确的前缀表达式并构造表达式----1");
            System.out.println("用带括弧的中缀表达式输出表达式----------------------2");
            System.out.println("对某一变量的赋值,变量的初值为0---------------------3");
            System.out.println("对算术表达式求值----------------------------------4");
            System.out.println("构造一个新的复合表达式-----------------------------5");

            while (true) {
                try {
                    Scanner input = new Scanner(System.in);
                    chance = input.nextInt();
                    if (chance > 0 && chance <=5) break;
                    else System.out.println("输入超过系统范围,请重新输入!");
                } catch (InputMismatchException e) {
                    System.out.println("非法输入,请重新输入!");
                }
            }
            switch (chance) {
                case 1:
                    System.out.println("输入语法正确的前缀表达式");
                    Scanner expre = new Scanner(System.in);
                    expression = expre.next();
                    ReadExpre(expression);
                    break;
                case 2:
                    WriteExpre();
                    break;
                case 3:
                    System.out.println("请输入要赋值的元素和要赋给的值,未赋值的元素默认值为0");
                    Scanner scanner = new Scanner(System.in);
                    String V = scanner.next();
                    String c = scanner.next();
                    Assign(V, c);
                    break;
                case 4:
                    Value();
                    break;
                case 5:
                    System.out.println("请依次输入运算符,表达式1,表达式2");
                    Scanner com = new Scanner(System.in);
                    String p = com.next();
                    String e1 = com.next();
                    String e2 = com.next();
                    CompoundExpr(p, e1, e2);
                    break;
            }
            System.out.println("请选择下一步操作");
        }
    }
}

勉强用java实现了前缀算数表达式生成二叉树,写的不好望各位见谅。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值