二叉樹(Binary Tree)

二叉樹是n個結點所構成的集合,它或爲空樹或爲非空樹。

對於非空樹T:1.有且僅有一個稱之爲根的結點;2.除根節點之外的其餘結點分爲兩個互不相交的子集T1和T2,分別稱爲左子樹和右子樹,且T1和T2也都是二叉樹。

滿二叉樹:深度爲k且含有2^{k}-1個節點的二叉樹。

完全二叉樹:深度爲k的,有n個結點的二叉樹,當且僅當其每一個結點都與深度爲k的滿二叉樹中編號從1-n的結點一一對應,稱之爲完全二叉樹。

    

二叉樹的性質

1.在二叉樹的第i層上至多有2^{i-1}個結點(i >= 1)。

2.深度爲k的二叉樹至多有2^{k}-1個結點(k >= 1)。

3.對任何一顆二叉樹T,若其終端節點數(葉子節點數)爲a ,度(結點擁有的子樹數)爲2的節點數爲b ,則 a = b + 1

4.具有n個結點的完全二叉樹的深度爲floor(\log _{2}n)+1 

5.如果一顆含有n個結點的完全二叉樹的結點按層序編號(即從上到下,從左到右編號),如果某個結點的編號爲i,那麼它的左孩子的編號爲2*i ,若2*i > n則表示結點i無左孩子,右孩子的編號爲2*i+1

下面是Java實現的二叉樹,裏面包括 建樹,樹的遍歷,求樹的深度,節點個數,樹的路徑長度,樹的帶權路徑長度,根節點到葉子節點組成的數字之和 

import java.util.Scanner;
/**
 * 二叉樹
 * 包括前序,中序,後序遍歷
 * 求樹的深度,節點個數,樹的路徑長度,樹的帶權路徑長度,根節點到葉子節點組成的數字之和
 * @author tiny_spot
 *
 */
public class BinaryTree {
	static Scanner s = new Scanner(System.in);
	public static void main(String []args) {
		System.out.println("樹的葉子節點的左右節點用0表示,前序輸入");
		BiTree root = new BiTree();
		createTree(root);
		preOrder(root);
		System.out.println();
		inOrder(root);
		System.out.println();
		postOrder(root);
		System.out.println();
		System.out.println("深度:"+depth(root));
		System.out.println("節點個數:"+nodeCnt(root));
		System.out.println("數字之和:"+numberSum(root, 0));
		System.out.println("樹的路徑長度:"+treePathLen(root ,0));
		System.out.println("樹的帶權路徑長度:"+weightPathLen(root ,0));
	}
	/**
	 * 創建二叉樹
	 * @param root
	 */
	public static void createTree(BiTree root) {
		int t = s.nextInt();
		root.setData(t);
		if(t == 0)
			return ;
		else {
			root.setData(t);
			root.left = new BiTree();
			createTree(root.left);
			if(root.left.getData() == 0)
				root.left = null;
			root.right = new BiTree();
			createTree(root.right);
			if(root.right.getData() == 0)
				root.right = null;
		}
	}
	/**
	 * 先序遍歷
	 * @param root
	 */
	public static void preOrder(BiTree root) {
		if(root == null)
			return;
		System.out.print(root.getData()+" ");
		preOrder(root.left);
		preOrder(root.right);
	}
	/**
	 * 中序遍歷
	 * @param root
	 */
	public static void inOrder(BiTree root) {
		if(root == null)
			return;
		inOrder(root.left);
		System.out.print(root.getData()+" ");
		inOrder(root.right);
	}
	/**
	 * 後序遍歷
	 * @param root
	 */
	public static void postOrder(BiTree root) {
		if(root == null)
			return ;
		postOrder(root.left);
		postOrder(root.right);
		System.out.print(root.getData()+" ");
	}
	/**
	 * 計算二叉樹的深度
	 * @param root
	 * @return 二叉樹的深度
	 */
	public static int depth(BiTree root) {
		if(root == null)
			return 0;
		int left = 1+depth(root.left);
		int right = 1+depth(root.right);
		return left > right ? left : right;
	}
	/**
	 * 計算二叉樹節點個數
	 * @param root
	 * @return 二叉樹節點個數
	 */
	public static int nodeCnt(BiTree root) {
		if(root == null)
			return 0;
		int left = nodeCnt(root.left);
		int right = nodeCnt(root.right);
		return 1+left+right;
	}
	/**
	 * 求所有根到葉子節點組成的數字之和                                 1
	 * 所有路徑:1->2->4, 1->2->5, 1->3      2  3
	 * 124+125+13=262                    4  5 
	 * @param root 樹的根節點
	 * @param n 一開始的數字
	 * @return 數字之和
	 */
	public static int numberSum(BiTree root ,int n) {
		if(root == null)
			return 0;
		int left = numberSum(root.left , n*10+root.getData());
		int right = numberSum(root.right, n*10+root.getData());
		if(left+right == 0)
			return n*10+root.getData();
		return left + right;
	}
	/**
	 * 求樹的路徑長度:即從樹根到每一個節點的路徑長度之和
	 * @param root
	 * @param n
	 * @return 樹的路徑長度之和
	 */
	public static int treePathLen(BiTree root ,int n) {
		if(root == null)
			return 0;
		int left = treePathLen(root.left ,n+1);
		int right = treePathLen(root.right, n+1);
		return left + right + n;
	}
	/**
	 * 求樹的帶權路徑長度:即樹中所有葉子節點的帶權路徑長度之和
	 * 節點的帶權路徑長度:從該節點到樹根之間的路徑長度與節點上權值的乘積
	 * @param root
	 * @param n
	 * @return
	 */
	public static int weightPathLen(BiTree root ,int n) {
		if(root == null)
			return 0;
		int left = weightPathLen(root.left, n+1);
		int right = weightPathLen(root.right, n+1);
		if(left+right == 0)//若左右子樹的帶權路徑長度爲0,則說明該節點是葉子節點
			return n*root.getData();
		return left + right;
	}
}
class BiTree{
	public BiTree left = null;
	public BiTree right = null;
	private int data ;
	public void setData(int data) {
		this.data = data;
	}
	public int getData() {
		return data;
	}
}
//1 2 3 0 0 4 5 0 6 0 0 7 0 0 0
//1 2 4 0 0 5 0 0 3 0 0
//1 3 7 0 0 5 0 0 6 2 0 0 4 0 0

 

 

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