二叉樹層次、先根序、後根序、打印操作

定義節點類

package pri.lr.java_tools.trees;

public class TreeNode<T> {
	private T value;
	private TreeNode<T> parent;
	private TreeNode<T> leftChild;
	private TreeNode<T> rightChild;
	
	public TreeNode() {
	}

	public TreeNode(T value) {
		this.value = value;
	}
		
	public T getValue() {
		return value;
	}

	public void setValue(T value) {
		this.value = value;
	}

	public TreeNode<T> getParent() {
		return parent;
	}

	public void setParent(TreeNode<T> parent) {
		this.parent = parent;
	}

	public TreeNode<T> getLeftChild() {
		return leftChild;
	}

	public void setLeftChild(TreeNode<T> leftChild) {
		this.leftChild = leftChild;
	}

	public TreeNode<T> getRightChild() {
		return rightChild;
	}

	public void setRightChild(TreeNode<T> rightChild) {
		this.rightChild = rightChild;
	}
	
	public void setInfo(T value, TreeNode<T> leftChild, TreeNode<T> rightChild){
		this.value = value;
		
	}
	
	public void setChildren(T value, TreeNode<T> leftChild, TreeNode<T> rightChild){
		this.leftChild = leftChild;
		this.rightChild = rightChild;
	}
}

定義二叉樹類:

package pri.lr.java_tools.trees;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

/**
 * 二叉樹,提供二叉樹的基本操作
 * @author 57721
 *
 */
public class BinaryTree<T> {
	private TreeNode<T> root = null;
	private int treeNodeCount;
	
	private Queue<TreeNode<T>> notFullNodeQue = new LinkedList<>();
	
	public BinaryTree(){}
	
	/**
	 * 插入到最後的位置
	 * @param value
	 * @return
	 */
	public boolean add(T value){
		TreeNode<T> oneNode = new TreeNode<>(value);
		if(root == null) {
			root = oneNode;
			treeNodeCount++;
			notFullNodeQue.add(root);
			return true;
		}
		
		if(notFullNodeQue.peek().getLeftChild() == null) {
			notFullNodeQue.peek().setLeftChild(oneNode);
			notFullNodeQue.offer(oneNode);
			treeNodeCount++;
			return true;
		}
		if(notFullNodeQue.peek().getRightChild() == null) {
			notFullNodeQue.peek().setRightChild(oneNode);
			notFullNodeQue.offer(oneNode);
			treeNodeCount++;
			notFullNodeQue.poll();
		}
		return false;
	}
	
	public void printTreeByPreOrder(){
		System.out.println("先序遍歷:");
		preOrder(root);
		System.out.println();
	}
	
	public void printTreeByInOrder(){
		System.out.println("中序遍歷");
		InOrder(root);
		System.out.println();
	}
	
	public void printTreeByPostOrder(){
		System.out.println("後序遍歷:");
		postOrder(root);
		System.out.println();
	}
	
	public void printTreeByLevel(){
		System.out.println("按層次遍歷:");
		if(root == null) {
			return;
		}
		levelOrder();
		System.out.println();
	}
	
	public void printTree(){
		System.out.println("打印二叉樹(從一側看):");
		printTree(root, 1);
		System.out.println();
	}
	
	public void printTreeUpDown(){
		System.out.println("打印二叉樹(自上到下):");
		if(root == null) {
			return;
		}
		int distance = (int) Math.pow(2, this.getHeight() -1) - 1;
		
		List<TreeNode<T>> list = new ArrayList<>();
		list.add(root);
		int pre = 0;// 始終指向每層最開始的一個,有可能不存在
		int aft = 0;//始終指向每層的最後一個,該位置所指的值一定存在
		int idx = 0;
		
		while(pre <= aft){
			for(idx = pre, pre = aft + 1; idx < pre; idx++) {
				printBlank(distance);				
				System.out.print(list.get(idx).getValue());				
				printBlank(distance);
				System.out.print(" ");
				
				if(list.get(idx).getLeftChild() != null) {
					list.add(list.get(idx).getLeftChild());
					aft++;
				}
				if(list.get(idx).getRightChild() != null) {
					list.add(list.get(idx).getRightChild());
					aft++;
				}
			}
			System.out.println();
			distance /= 2;
		}
	}
	
	

	
	public int getNodeCount(){
		return this.treeNodeCount;
	}
	
	public int getHeight(){
		return (int) (Math.log(this.treeNodeCount)/Math.log(2) + 1);
	}
	
	
	private void printBlank(int k) {
		for(int i = 0 ; i< k; i++) {
			System.out.print(" ");
		}
	}
	private void printTree(TreeNode<T> root, int h){
		if(root == null) return;
		printTree(root.getRightChild(), h + 1);
		for(int i = 0 ; i < h; i++) {
			System.out.print(" ");
		}
		System.out.println(root.getValue());
		printTree(root.getLeftChild(), h+1);
	}
	private void levelOrder() {
		Queue<TreeNode<T>> que = new LinkedList<>();
		que.offer(root);
		TreeNode<T> current = null;
		while(!que.isEmpty()){
			current = que.poll();
			System.out.print(current.getValue() + " ");
			if(current.getLeftChild() != null) {
				que.offer(current.getLeftChild());
			}
			if(current.getRightChild() != null) {
				que.offer(current.getRightChild());
			}
		}
	}

	private void postOrder(TreeNode<T> root2) {
		if(root2 != null) {
			postOrder(root2.getLeftChild());
			postOrder(root2.getRightChild());
			System.out.print(root2.getValue() + " ");
		}
	}

	private void preOrder(TreeNode<T> root1){
		if(root1 != null) {
			System.out.print(root1.getValue() + " ");
			preOrder(root1.getLeftChild());
			preOrder(root1.getRightChild());
		}
	}
	private void InOrder(TreeNode<T> root3){
		if(root3 != null) {
			InOrder(root3.getLeftChild());
			System.out.print(root3.getValue() + " ");
			InOrder(root3.getRightChild());
		}
	}
	

}

測試結果:

package pri.lr.java_tools.trees;

public class Demo {

	public static void main(String[] args) {
		BinaryTree<String> oneTree = new BinaryTree<>();
		oneTree.add("A");
		oneTree.add("B");
		oneTree.add("C");
		oneTree.add("D");
		oneTree.add("E");
		oneTree.add("F");
		oneTree.add("G");
		oneTree.add("H");
		
		oneTree.printTree();
		oneTree.printTreeUpDown();
		oneTree.printTreeByInOrder();
		oneTree.printTreeByPreOrder();
		oneTree.printTreeByPostOrder();
		oneTree.printTreeByLevel();
	}
}

結果:

打印二叉樹(從一側看):
   G
  C
   F
 A
   E
  B
   D
    H

打印二叉樹(自上到下):
       A        
   B       C    
 D   E   F   G  
H 
中序遍歷
H D B E A F C G 
先序遍歷:
A B D H E C F G 
後序遍歷:
H D E B F G C A 
按層次遍歷:
A B C D E F G H 

 

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