需求分析:
①輸入樹葉數
②輸入樹葉權值
③輸出最優二元正則樹的遍歷
效果展示:
效果解說:
例如:“16(0)”,其中16是節點的權值,0是節點的層數。0層代表根節點
涉及類:
①TreeNodeMananger : 根據樹葉的權值或者樹葉節點計算根節點,遍歷樹(先根,中根,後根)
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.InputMismatchException;
/**
* 類樹節點管理類
*
* @author Lance 2014-12-22
* @version 1.0
*/
public class TreeNodeManager {
//根據節點,獲取根節點
public static TreeNode getRootNode(TreeNode[] nodes) {
//計算最優樹
for(int i=0 ; i<nodes.length-1 ; i++) {
Arrays.sort(nodes);
// for(TreeNode node : nodes) { //調試代碼
// if(node == null) continue;
// System.out.print(new BigDecimal(node.getNum()).toString()+" ");
// }
// System.out.println("\n--------------------");
//有序樹
TreeNode parent =
new TreeNode(nodes[i], nodes[i].getNum()+nodes[i+1].getNum(), nodes[i+1]);
TreeNode zero = new TreeNode(null, 0, null);
nodes[i] = zero;
nodes[i+1] = parent;
}
TreeNode rootNode = nodes[nodes.length-1];
return rootNode;
}
//根據樹葉權值,獲取根節點
public static TreeNode getRootNode(double[] num) {
TreeNode[] nodes = new TreeNode[num.length];
for(int i=0 ; i<num.length ; i++) {
nodes[i] = new TreeNode(null, num[i], null);
}
return getRootNode(nodes);
}
/** If successfully print node, return true; else false;
* 如果打印節點成功,返回true;否則返回false
*
* @param node Parent node
* @param level The level of node
*/
public static boolean printNodes(TreeNode node, int level, int model) throws InputMismatchException {
if(node==null) return false;
TreeNode leftChild = node.getLeftChild();
TreeNode rightChild = node.getRightChild();
// 先根次序遍歷
if(model == TreeNodeConstants.BEFORE) {
System.out.print(new BigDecimal(node.getNum()).toString()+"("+level+") ");
printNodes(leftChild, level+1, model);
printNodes(rightChild, level+1, model);
}
//中根次序遍歷
else if(model == TreeNodeConstants.MIDDLE) {
printNodes(leftChild, level+1, model);
System.out.print(new BigDecimal(node.getNum()).toString()+"("+level+") ");
printNodes(rightChild, level+1, model);
}
// 後根次序遍歷
else if(model == TreeNodeConstants.AFTER) {
printNodes(leftChild, level+1, model);
printNodes(rightChild, level+1, model);
System.out.print(new BigDecimal(node.getNum()).toString()+"("+level+") ");
}
else {
throw new InputMismatchException("錯誤遍歷模式");
}
return true;
}
}
②TreeNodeConstants : 保存樹節點遍歷模式
<span style="font-size:18px;">/**
* 樹節點遍歷模式常量類
*
* @author Lance 2014-12-22
* @version 1.0
*/
interface TreeNodeConstants {
public static final int BEFORE = 0; //前根次序遍歷
public static final int MIDDLE = 0; //中根次序遍歷
public static final int AFTER = 0; //後根次序遍歷
}</span>
③TreeNode : 保存了樹節點信息
/**
* Class about tree node
* Implements the interface Comparable, in order to make it comparable
* 樹節點類
* 實現了Comparable接口,使該類對象能夠排序
*
* @author Lance 2014-12-22
* @version 1.0
*/
public class TreeNode implements Comparable<TreeNode> {
private double num = 0;
// private int level = 0; //層數
private TreeNode parent = null; //父節點
private TreeNode leftChild=null; //左子節點
private TreeNode rightChild=null; //右子節點
public TreeNode(TreeNode leftChild, double num, TreeNode rightChild) {
this.leftChild = leftChild;
this.num = num;
this.rightChild = rightChild;
}
//Order by num (根據num的數值排序)
@Override
public int compareTo(TreeNode t) {
return (int)Math.signum(this.getNum()-t.getNum());
}
public double getNum() {
return num;
}
public TreeNode getParent() {
return parent;
}
public TreeNode getLeftChild() {
return leftChild;
}
public TreeNode getRightChild() {
return rightChild;
}
}
④TreeDemo : 效果演示
//最優二元樹計算、以及遍歷
import java.util.Scanner;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.math.BigDecimal;
public class TreeDemo {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
//Input number of leaf (輸入樹葉數)
System.out.print("Input number of leaf(輸入樹葉數) : ");
int n = scan.nextInt();
if(n < 1) return ;
//Input data (輸入樹葉權值)
double[] num = new double[n];
System.out.print("Input data (輸入樹葉權值) : ");
for(int i=0 ; i<num.length ; i++) {
num[i] = scan.nextDouble();
}
// TreeNode[] nodes = new TreeNode[num.length]; //調試代碼
// for(int i=0 ; i<num.length ; i++) {
// nodes[i] = new TreeNode(null, num[i], null);
// }
//Get root node (獲取根節點)
// TreeNode rootNode = TreeNodeManager.getRootNode(nodes); //調試代碼
TreeNode rootNode = TreeNodeManager.getRootNode(num);
//Print nodes (打印節點)
TreeNodeManager.printNodes(rootNode, 0, TreeNodeConstants.MIDDLE);
// TreeNodePrinter.printNodes(rootNode, 0, 4); //調試代碼
}
}
類功能說明:
①可單獨使用TreeNodeManager的遍歷功能,不限於二元正則樹
②可根據TreeNodeConstants選擇遍歷的模式(先根次序遍歷,中根,後根),依照需求選擇
程序缺陷:
①使用了BigDecimal:容易造成額外的內存開支。
使用原因:美觀
@author Lance 2014-12-22 20:20