二叉樹是n個結點所構成的集合,它或爲空樹或爲非空樹。
對於非空樹T:1.有且僅有一個稱之爲根的結點;2.除根節點之外的其餘結點分爲兩個互不相交的子集T1和T2,分別稱爲左子樹和右子樹,且T1和T2也都是二叉樹。
滿二叉樹:深度爲k且含有個節點的二叉樹。
完全二叉樹:深度爲k的,有n個結點的二叉樹,當且僅當其每一個結點都與深度爲k的滿二叉樹中編號從1-n的結點一一對應,稱之爲完全二叉樹。
二叉樹的性質:
1.在二叉樹的第i層上至多有個結點(i >= 1)。
2.深度爲k的二叉樹至多有個結點(k >= 1)。
3.對任何一顆二叉樹T,若其終端節點數(葉子節點數)爲a ,度(結點擁有的子樹數)爲2的節點數爲b ,則 a = b + 1
4.具有n個結點的完全二叉樹的深度爲floor()+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