树状形式打印二叉树

树状结构打印二叉树,难点在于确定节点之间的间隙。由于每个节点内容的长度不统一,在此处理方法是:选取每个最长的长度作为标准,其他的节点用空格符补齐。

对一个高为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 level = new ArrayList();
		List> wholeTree = new ArrayList>();
		int maxLength = 0;
		level.add(root);
		while(level.size() > 0){
			wholeTree.add(level);
			List newLevel = new ArrayList();
			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 list = new ArrayList();
		list.add(root);
		return insert(position,s,list);
	}

	public boolean insert(String position, String s, List list){
		if(list.size() == 0){
			return false;
		}
		List childList = new ArrayList();
		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;
			}
		}
	}
}

下面的截图是运行效果:


你可能感兴趣的:(java)