数据结构(Java)——二叉树的应用
忙碌是一种幸福,让我们没时间体会痛苦;奔波是一种快乐,让我们真实地感受生活;疲惫是一种享受,让我们无暇空虚。
1.表达式的二叉树求解
1.1 构建表达式树
表达式树扩展了LinkedBinaryTree类,提供了一个构造函数,用于把表达式树合成一棵新树,还提供了evaluate方法,用于一旦表达式树构造好之后可以对其进行递归计算。
package ds.java.ch10;
import ds.java.ch06.listImpl.ArrayUnorderedList;
import ds.java.ch06.listImpl.UnorderedListADT;
import ds.java.ch10.btreeImpl.BinaryTreeNode;
import ds.java.ch10.btreeImpl.LinkedBinaryTree;
/**
* @author LbZhang
* @version 创建时间:2015年11月23日 下午2:20:53
* @description 表达式树
*
* 表达式树是操作符和操作数集合结构
*/
public class ExpressionTree extends LinkedBinaryTree<ExpressionTreeOp> {
/**
* 无参构造函数
*
*/
public ExpressionTree() {
super();
}
/**
* expressionTree的构造函数
*
* @param eobj
* @param left
* @param right
*/
public ExpressionTree(ExpressionTreeOp eobj, ExpressionTree left,
ExpressionTree right) {
root = new BinaryTreeNode<ExpressionTreeOp>(eobj, left, right);
}
/**
* 表达式树的计算
*
* @return
*/
public int evaluateTree() {
return evaluateNode(root);
}
/**
* 结点的递归计算
*
* @param root
* @return
*/
private int evaluateNode(BinaryTreeNode<ExpressionTreeOp> root) {
int result, op1, op2;
ExpressionTreeOp temp;
if (root == null) {
result = 0;
} else {
temp = (ExpressionTreeOp) root.getElement();
if (temp.isOperator()) {
op1 = evaluateNode(root.getLeft());
op2 = evaluateNode(root.getRight());
result = computeTerm(temp.getOperator(), op1, op2);
}else{
result = temp.getValue();
}
}
return result;
}
/**
* 计算规则的定义实现
*
* @param operator
* @param op1
* @param op2
* @return
*/
private int computeTerm(char operator, int op1, int op2) {
int result = 0;
if (operator == '+') {
result = op1 + op2;
} else if (operator == '-') {
result = op1 - op2;
} else if (operator == '*') {
result = op1 * op2;
} else if (operator == '/') {
result = op1 / op2;
}
return result;
}
public String printTree() {
UnorderedListADT<BinaryTreeNode<ExpressionTreeOp>> nodes = new ArrayUnorderedList<BinaryTreeNode<ExpressionTreeOp>>();
UnorderedListADT<Integer> levelList = new ArrayUnorderedList<Integer>();
BinaryTreeNode<ExpressionTreeOp> current;
String result = "";
int printDepth = this.getHeight();
int possibleNodes = (int) Math.pow(2, printDepth + 1);
int countNodes = 0;
nodes.addToRear(root);
Integer currentLevel = 0;
Integer previousLevel = -1;
levelList.addToRear(currentLevel);
while (countNodes < possibleNodes) {
countNodes = countNodes + 1;
current = nodes.removeFirst();
currentLevel = levelList.removeFirst();
if (currentLevel > previousLevel) {
result = result + "\n\n";
previousLevel = currentLevel;
for (int j = 0; j < ((Math.pow(2, (printDepth - currentLevel))) - 1); j++)
result = result + " ";
} else {
for (int i = 0; i < ((Math.pow(2,
(printDepth - currentLevel + 1)) - 1)); i++) {
result = result + " ";
}
}
if (current != null) {
result = result + (current.getElement()).toString();
nodes.addToRear(current.getLeft());
levelList.addToRear(currentLevel + 1);
nodes.addToRear(current.getRight());
levelList.addToRear(currentLevel + 1);
} else {
nodes.addToRear(null);
levelList.addToRear(currentLevel + 1);
nodes.addToRear(null);
levelList.addToRear(currentLevel + 1);
result = result + " ";
}
}
return result;
}
}
1.2 构建表达式结点类
结点类中主要包含三部分,结点类型、结点的内容(char操作符或者int操作数)
package ds.java.ch10;
/**
* @author LbZhang
* @version 创建时间:2015年11月23日 下午2:21:11
* @description
*
* 表达式树中的元素 元素类
*/
public class ExpressionTreeOp {
private int termType;
private char operator;
private int value;
public ExpressionTreeOp() {
}
/**
* 3个参数的构造函数的
*
* @param termType
* @param operator
* @param value
*/
public ExpressionTreeOp(int termType, char operator, int value) {
super();
this.termType = termType;
this.operator = operator;
this.value = value;
}
/**
* 判断是不是操作符号
* @return boolean
*/
public boolean isOperator() {
return (termType==1);
}
public char getOperator() {
return operator;
}
public int getValue() {
return value;
}
@Override
public String toString() {
if(termType==1){
return operator+"";
}
else{
return value+"";
}
}
}
1.3 表达式的组装类和测试类
package ds.java.ch10;
import java.util.Scanner;
import java.util.Stack;
/**
* @author LbZhang
* @version 创建时间:2015年11月23日 下午4:24:04
* @description 类说明
*/
public class PostfixEvaluator {
private String expression;
private Stack<ExpressionTree> treeStack;// 栈
/**
* Sets up this evalutor by creating a new stack.
*/
public PostfixEvaluator() {
treeStack = new Stack<ExpressionTree>();
}
/**
* Retrieves and returns the next operand off of this tree stack.
*
* @param treeStack
* the tree stack from which the operand will be returned
* @return the next operand off of this tree stack
*/
private ExpressionTree getOperand(Stack<ExpressionTree> treeStack) {
ExpressionTree temp;
temp = treeStack.pop();
return temp;
}
/**
* Evaluates the specified postfix expression by building and evaluating an
* expression tree.
*
* @param expression
* string representation of a postfix expression
* @return value of the given expression
*/
public int evaluate(String expression) {
ExpressionTree operand1, operand2;//两个计算需要使用的操作数
char operator;
String tempToken;
Scanner parser = new Scanner(expression);
while (parser.hasNext()) {
tempToken = parser.next();
operator = tempToken.charAt(0);
if ((operator == '+') || (operator == '-') || (operator == '*')
|| (operator == '/')) {
operand1 = getOperand(treeStack);
operand2 = getOperand(treeStack);
//如果是操作符就进行计算
treeStack.push(new ExpressionTree(new ExpressionTreeOp(1,
operator, 0), operand2, operand1));
} else {
treeStack.push(new ExpressionTree(new ExpressionTreeOp(2, ' ',
Integer.parseInt(tempToken)), null, null));
}
}
return (treeStack.peek()).evaluateTree();
}
/**
* Returns the expression tree associated with this postfix evaluator.
*
* @return string representing the expression tree
*/
public String getTree() {
return "Notree";
//return (treeStack.peek()).printTree();
}
}
package ds.java.ch10;
import java.util.Scanner;
/**
* @author LbZhang
* @version 创建时间:2015年11月23日 下午4:00:24
* @description 类说明
*/
public class PostfixTester {
public static void main(String[] args) {
String expression, again;
int result;
Scanner in = new Scanner(System.in);
PostfixEvaluator evaluator = new PostfixEvaluator();
expression = "5 3 - 4 * 9 +";
result = evaluator.evaluate(expression);
System.out.println();
System.out.println("That expression equals " + result);
System.out.println("The Expression Tree for that expression is: ");
System.out.println(evaluator.getTree());
}
}
2. 二叉树行为的决策树
2.1 决策树类的构建
决策树类主要是对二叉树的调用和扩展实现,实现决策树对象初始化和用于决策的程序实现。
package ds.java.ch10;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.List;
import java.util.Scanner;
import ds.java.ch10.btreeImpl.LinkedBinaryTree;
/**
* @author LbZhang
* @version 创建时间:2015年11月23日 下午5:15:28
* @description 决策树类的构建
*
*/
public class DecisionTree {
private LinkedBinaryTree<String> tree;
/**
* 使用文件中的内容初始化二叉树的关联关系
*
* @param filename
* @throws FileNotFoundException
*
* 这个地方需要学习的是树的链表存储的构建方式: 在链表树的存储过程中可以首先添加结点,然后根据关联关系表来添加关联
* 或者在构建tree结点的同时设置连边关联
*
*/
public DecisionTree(String filename) throws FileNotFoundException {
File inputFile = new File(filename);
Scanner scan = new Scanner(inputFile);
int numberNodes = scan.nextInt();// 整型读出
scan.nextLine();
int root = 0;
int left, right;
// 用户存储二叉树的列表
List<LinkedBinaryTree<String>> nodes = new java.util.ArrayList<LinkedBinaryTree<String>>();
// 将当前的元素包装之后放到树里面
for (int i = 0; i < numberNodes; i++)
nodes.add(i, new LinkedBinaryTree<String>(scan.nextLine()));
// 一行一行的读数据 给每一个二叉树分配自己的位置
while (scan.hasNext()) {
root = scan.nextInt();
left = scan.nextInt();
right = scan.nextInt();
scan.nextLine();
// 根据索引组合树
nodes.set(
root,
new LinkedBinaryTree<String>((nodes.get(root))
.getRootElement(), nodes.get(left), nodes
.get(right)));
}
// 最后将根结点对象引用指向tree
tree = nodes.get(root);
}
/**
* Follows the decision tree based on user responses.
*/
public void evaluate() {
LinkedBinaryTree<String> current = tree;
Scanner scan = new Scanner(System.in);
while (current.size() > 1) {
System.out.println(current.getRootElement());
if (scan.nextLine().equalsIgnoreCase("N"))
current = current.getLeft();
else
current = current.getRight();
}
System.out.println("Output the Judge Result :"+current.getRootElement());
}
}
2.2 测试类以及测试结果
package ds.java.ch10;
import java.io.FileNotFoundException;
/**
* @author LbZhang
* @version 创建时间:2015年11月23日 下午5:13:43
* @description 背部疼痛诊断器
*
*/
public class BackPainAnalyzer {
/**
* Asks questions of the user to diagnose a medical problem.
*/
public static void main(String[] args) throws FileNotFoundException {
System.out.println("So, you're having back .");
DecisionTree expert = new DecisionTree("input.txt");
expert.evaluate();
}
}
测试结果:
踏实 踏踏实实~