在用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);
}
如此,就可以直接在非本类中调用该方法且不需要输入参数了。