二叉树计算节点的计算值
Binary trees can be used to represent mathematical formulas. For example, a mathematical formula 3*((7+1)/4)+(17-5) can be stored as a binary tree and then we can calculate the value of the formula recursively like the following:
Given the above class Node, write a recursive method to find the value of a formula tree e.g. 18 in the above tree. Assume that there are only four operators +(plus), - (minus), * (multiplication), and / (division) allowed in the formula.
二叉树可以用来表示数学公式。例如,数学公式3*((7+1)/4)+(17-5)可以存储为二叉树,然后我们可以递归地计算公式的值,如下所示
给定上面的类Node,编写一个递归方法来查找上面树中公式树的值,例如18。假设公式中只允许四个运算符+(加)、-(减)、*(乘)和/(除)。
建立Node类存储每个节点
将节点分为符号节点和数字节点两种,分别有不同的构造器构造,符号节点需要保存他的类型,左子树,右子树,运算符
数字节点需要保存类型和数字
enum NodeTypes { NUMBER, OPERATOR }
class Node {
NodeTypes type; // Which type of node is this?
double number; // The value in a node of type NUMBER.
char operator; // The operator in a node Of type OPERATOR.
Node left; // Pointer to left subtree
Node right; // Pointer to right subtree
Node(char operator, Node left, Node right) { // Constructor for creating a node of type OPERATOR
type = NodeTypes.OPERATOR;
this.operator = operator;
this.left = left;
this.right = right;
}
Node(double number) { // Constructor for creating a node Of type NUMBER
type = NodeTypes. NUMBER;
this.number = number;
}
}
构造表达式二叉树
构造二叉树其实就是对节点本身的构造以及依赖关系,并且指定根节点
Node a = new Node('+', new Node(7),new Node(1));
Node b = new Node('/', a,new Node(4));
Node c = new Node('*', new Node(3),b);
Node d = new Node('-', new Node(17),new Node(5));
Node root = new Node('+', c,d);
计算函数以及递归
思考一个问题,从简单的三个节点开始,假如左节点和右节点都是数字
public static double calculate(double a, double b, char operator){
double result = 0;
switch (operator){
case '+':
result = a + b;
break;
case '-':
result = a - b;
break;
case '*':
result = a * b;
break;
case '/':
result = a / b;
break;
}
return result;
}
但实际上,左节点和右节点可能是符号节点,那我们需要建立一个方法递归找到左右均为数字的节点,将其计算并且替代父节点,通过左右递归,始终保证节点的类型是数字时返回
public static Node treecalculate(Node root){
// 终止条件:节点类型是数字
if(root.type == NodeTypes.NUMBER){
return root;
}
if(root.left.type != NodeTypes.NUMBER){
root.left = treecalculate(root.left);
}
if(root.right.type != NodeTypes.NUMBER){
root.right = treecalculate(root.right);
}
return root = new Node(calculate(root.left.number,root.right.number,root.operator));
}
代码
public class RecursionTree {
// create the tree
public static void main(String[] args) {
Node a = new Node('+', new Node(7),new Node(1));
Node b = new Node('/', a,new Node(4));
Node c = new Node('*', new Node(3),b);
Node d = new Node('-', new Node(17),new Node(5));
Node root = new Node('+', c,d);
System.out.println(treecalculate(root).number);// 传入节点可以计算出每一个符号对应的表达式值
}
//make recursive method
public static Node treecalculate(Node root){
// left is not number
if(root.type == NodeTypes.NUMBER){
return root;
}
// xiangbanfa ba zuobina de biancheng number
if(root.left.type != NodeTypes.NUMBER){
root.left = treecalculate(root.left);
}
if(root.right.type != NodeTypes.NUMBER){
root.right = treecalculate(root.right);
}
return root = new Node(calculate(root.left.number,root.right.number,root.operator));
}
public static double calculate(double a, double b, char operator){
double result = 0;
switch (operator){
case '+':
result = a + b;
break;
case '-':
result = a - b;
break;
case '*':
result = a * b;
break;
case '/':
result = a / b;
break;
}
return result;
}
}
enum NodeTypes { NUMBER, OPERATOR }
class Node {
NodeTypes type; // Which type of node is this?
double number; // The value in a node of type NUMBER.
char operator; // The operator in a node Of type OPERATOR.
Node left; // Pointer to left subtree
Node right; // Pointer to right subtree
Node(char operator, Node left, Node right) { // Constructor for creating a node of type OPERATOR
type = NodeTypes.OPERATOR;
this.operator = operator;
this.left = left;
this.right = right;
}
Node(double number) { // Constructor for creating a node Of type NUMBER
type = NodeTypes. NUMBER;
this.number = number;
}
}
通宵好几个晚上了,我下学期一定好好学习,立一个flag!!!!!