最優二元正則樹 Java實現

需求分析:

①輸入樹葉數

②輸入樹葉權值

③輸出最優二元正則樹的遍歷


效果展示:



效果解說:

例如:“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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章