表达二叉树的构建

    在用java实现表达式二叉树之前,先要明白究竟什么是表达式二叉树。

    举个例子,有表达式“(a+b×(c-d))-e/f”,现在将该表达式通过树形图来表示。那么究竟该如何表示呢?下图就是一个绘制好的表达式二叉树模型。所谓的规则就是:运算符放在结点位置,而数字放在子节点位置。通过这样的规则构成一个二叉树,又由于存储的是一个表达式,因此称为“二叉树表达式”

                                                                        

    那么这个二叉树究竟如何建立呢?举例1+2+3

    首先取出两个数和一个运算符,讲道理按规则做事,如下图。

                                                         

    此时,可以假定上图表达式算出某个结果(假设x),并需要作为一个数字,和再取出的一个数字与运算符构成父子节点,如下图

                                                     

于是最后实际形成

                                                

    总结一下构建步骤:

        创建节点对象,按照规则取出2个数字和1个运算符,存放在对应位置,构建成为一个新的节点再重复该步骤。

        但其实在具体代码中还有别的小操作,比如从表达式中取出的操作符和数字操作之前分别放在哪,操作到哪一步结束。因此,具体步骤如下:

        1.创建结点对象

        2.读取表达式,分别出运算符和数字,分别存放在相对应的列表中

        3.取出前两个数字和一个操作符,构建成一个新的结点,再次放入数字列表

        4.重复步骤3,直到操作符取完

        5.让根节点等于最后的结点

首先写一个结点类,顺便给该节点定义两个左右结点属性方便后面操作。为了简单方法只写了getdata

public class Node {

	Node left;
	Node right;
	String data;
	
	public Node() {}
	
	public Node(String data) {
		this.data = data;
	}
	
	public String getdata() {
		return data;		
	}
}

实现表达式二叉树类,为了简单我这里并没有去得到一个表达式然后区分运算符和字符。没错我就是这么懒大家不要学我。

        让根节点等于最后的结点是为了输出的时候找到最开始的输出节点。

        用递归的思想完成简单的中序遍历。

public class Tree {

	Node root;
	
	public void creattree() {
		//声明一个数组,存放运算符
		ArrayList<Node> operslist = new ArrayList<Node>();
		//声明一个数组,存放节点数据
		ArrayList<Node> numberlist = new ArrayList<Node>();
		//将运算符和节点数据分别放进对应队列
		numberlist.add(new Node("1"));
		numberlist.add(new Node("3"));
		numberlist.add(new Node("2"));
		operslist.add(new Node("+"));
		operslist.add(new Node("+"));
		
		/**
		 * 第二步,取出前两个数字和一个操作符,组成一个新的数字节点
		 * 第三步,重复第二步,直到操作符取完为止
		 */
    	//循环取出运算符直到取完为止
    	while(operslist.size()>0){
    		//取出2个数字和一个运算符
    		Node num1=numberlist.remove(0);
			Node num2=numberlist.remove(0);
    		Node oper=operslist.remove(0);

    		oper.left=num1;
    		oper.right=num2;

    		numberlist.add(0,oper);
    		
    	}
		//让根节点等于最后一个节点
		root = numberlist.get(0);
	}
	
	
	public void output(Node node) {
		//假如左子节点null,结束递归
		if(node.left != null) {
			output(node.left);
		}
		System.out.print(node.getdata()+" ");
		//假如右子节点null,结束递归
		if(node.right != null) {
			output(node.right);
		}
	}
	
	public void output() {
		output(root);
	}
		
	public static void main(String[] args) {
		Tree tree = new Tree();
		tree.creattree();
		tree.output();
	}
}

       —————————————我是一个没有感情的分割线———————————————

       

        值得一提的是一个无关此处的一个小方法,许多时候我们写了需要传入参数的方法,比如下面代码中的

public void output(Node node){}

        这种情况下如果需要在其他类中调用这个方法,输入该node类的参数有时候比较麻烦 (不是所有方法输入参数都和get(index)一样),此时可以再写一个方法,在方法中调用需要输入参数的方法,如

public void output() {
	output(root);
}

        如此,就可以直接在非本类中调用该方法且不需要输入参数了。 

猜你喜欢

转载自blog.csdn.net/weixin_42621338/article/details/82432755