樹狀形式打印二叉樹

樹狀結構打印二叉樹,難點在於確定節點之間的間隙。由於每個節點內容的長度不統一,在此處理方法是:選取每個最長的長度作爲標準,其他的節點用空格符補齊。

對一個高爲h的二叉樹,最底層(葉子節點),第一個節點距離起始輸出間隙爲2^0 —1,節點之間的間隙爲2^1—1。倒數第二層,第一個節點距離起始輸出間隙爲2^1—1,節點之間的間隙爲2^2—1。即,對於第k層(從上往下數,根節點爲第一次),第一個節點距離起始輸出位置爲2^(h-k)—1,節點之間的間隙爲2^(h-k+1) —1。

在本例中,null**表示葉子節點的left、right節點。在插入節點時,輸入null**,在輸入節點內容,就可以完成插入操作。在代碼中,還額外實現了前、中、後序遍歷。

樹節點的代碼如下:

public class TreeNode {
	public String s;
	public TreeNode left;
	public TreeNode right;

	public TreeNode(){
		this.s = "null" + Tree.nullNum;
		Tree.nullNum++;
		left = null;
		right = null;
	}
}

樹的代碼如下:

import java.util.ArrayList;
import java.util.List;

public class Tree {
	public static int nullNum = 0;
	private TreeNode root;
	
	public Tree(){
		initTree();
	}

	public void initTree(){
		nullNum = 0;
		root = new TreeNode();
	}

	public String printTree(){
		String tree = "";
		List<TreeNode> level = new ArrayList<TreeNode>();
		List<List<TreeNode>> wholeTree = new ArrayList<List<TreeNode>>();
		int maxLength = 0;
		level.add(root);
		while(level.size() > 0){
			wholeTree.add(level);
			List<TreeNode> newLevel = new ArrayList<TreeNode>();
			for (int i = 0; i < level.size(); i++){
				TreeNode node = level.get(i);
				if (node.s.length() > maxLength){
					maxLength = node.s.length();
				}
				if (node.left != null && node.right != null){
					newLevel.add(node.left);
					newLevel.add(node.right);
				}
			}
			level = newLevel;
		}
		int height = wholeTree.size();
		for (int i = 0; i < height; i++){
			level = wholeTree.get(i);
			int spaceNum = (int) ((Math.pow(2, height - i - 1) - 1) * (maxLength + 1));
			for (int j = 0; j < spaceNum; j++){
				tree += " ";
			}
			tree += addSpace(level.get(0).s,maxLength);
			spaceNum = (int) ((Math.pow(2, height - i) - 1) * (maxLength + 1));
			for (int j = 1; j < level.size(); j++){
				for (int k = 0; k < spaceNum; k++){
					tree += " ";
				}
				tree += addSpace(level.get(j).s,maxLength);
			}
			tree += "\n";
		}
		System.out.println(tree);
		return tree;
	}
	
	public String addSpace(String s, int length){
		int initLength = s.length();
		for(int i = 0; i < (length - initLength) / 2; i++){
			s = " " + s;
		} 
		while(s.length() <= length){
			s += " ";
		}
		return s;
	}
	//插入節點
	public boolean insert(String position, String s){
		List<TreeNode> list = new ArrayList<TreeNode>();
		list.add(root);
		return insert(position,s,list);
	}

	public boolean insert(String position, String s, List<TreeNode> list){
		if(list.size() == 0){
			return false;
		}
		List<TreeNode> childList = new ArrayList<TreeNode>();
		for(int i = 0; i < list.size(); i++){
			TreeNode node = list.get(i);
			if (position.equals(node.s)){
				if (position.startsWith("null") && node.left == null && node.right == null){
					for (int j = 0; j < list.size(); j++){
						TreeNode temp = list.get(j);
						temp.left = new TreeNode();
						temp.right = new TreeNode();
					}
				}
				node.s = s;
				return true;
			}else{
				if (node.left != null){
					childList.add(node.left);
				}
				if (node.right != null){
					childList.add(node.right);
				}
			}
		}
		return insert(position,s,childList);
	}

	//前序遍歷
	public String preOrder(){
		return preOrder(root);
	}
	
	public String preOrder(TreeNode pivot){
		String tree = "";
		if (! pivot.s.startsWith("null")){
			tree += pivot.s + " " + preOrder(pivot.left) + " " + preOrder(pivot.right) + " ";
		}
		return tree;
	}

	//中序遍歷
	public String inOrder(){
		return inOrder(root);
	}

	public String inOrder(TreeNode pivot){
		String tree = "";
		if (! pivot.s.startsWith("null")){
			tree += inOrder(pivot.left) + " " + pivot.s + " " + inOrder(pivot.right) + " ";
		}
		return tree;
	}

	//後序遍歷
	public String postOrder(){
		return postOrder(root);
	}

	public String postOrder(TreeNode pivot){
		String tree = "";
		if (! pivot.s.startsWith("null")){
			tree += postOrder(pivot.left) + " " + postOrder(pivot.right) + " " + pivot.s + " ";
		}
		return tree;
	}
}

測試類的代碼如下

mport java.util.Scanner;


public class Test {
	public static void main(String[] args){
		Tree tree = new Tree();
		Scanner in = new Scanner(System.in);
		while(true){
			tree.printTree();
			System.out.println("請輸入需要插入的位置");
			String position = in.nextLine().trim().replace("\n", "");
			System.out.println("請輸入節點內容");
			String s = in.nextLine().trim().replace("\n", "");
			if(tree.insert(position, s) == false){
				System.out.println("你輸入的位置不存在...");
				break;
			}
		}
	}
}

下面的截圖是運行效果:


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