【二叉樹】二叉樹的建立與遍歷

1、定義

二叉樹是一個連通的無環圖,而且每個頂點的度不大於3。有根二叉樹還要知足根結點的度不大於2。有了根結點以後,每一個頂點定義了惟一的父結點,和最多2個子結點。函數

2、性質

  •  在非空二叉樹中,第i層的結點總數不超過, i>=1;
  •  深度爲h的二叉樹最多有個結點(h>=1),最少有h個結點;
  •  對於任意一棵二叉樹,若是其葉結點數爲N0,而度數爲2的結點總數爲N2,則N0=N2+1;
  •  具備n個結點的徹底二叉樹的深度爲(注:[ ]表示向下取整)
  • 有N個結點的徹底二叉樹各結點若是用順序方式存儲,則結點之間有以下關係:
  1. 若I爲結點編號則 若是I>1,則其父結點的編號爲I/2;
  2. 若是2*I<=N,則其左孩子(即左子樹的根結點)的編號爲2*I;若2*I>N,則無左孩子;
  3. 若是2*I+1<=N,則其右孩子的結點編號爲2*I+1;若2*I+1>N,則無右孩子。
  • 給定N個結點,能構成h(N)種不一樣的二叉樹。h(N)爲卡特蘭數的第N項。h(n)=C(2*n,n)/(n+1);
  • 設有i個枝點,I爲全部枝點的道路長度總和,J爲葉的道路長度總和J=I+2i。

3、二叉樹的建立

@Setter @Getter @ToString public class BinaryTree { private Object data;//當前節點數據
    private BinaryTree lChild;//當前節點左孩子
    private BinaryTree rChild;//當前節點右孩子
    private BinaryTree root;//根節點 //構造函數
    public BinaryTree (Object data){ this.data = data; } //建立二叉樹
    public void creatBinaryTree (Object data[]){ //將數據轉換爲節點存儲
        List<BinaryTree> list = new ArrayList<BinaryTree>(); for (Object tmpdata:data){ list.add(new BinaryTree(tmpdata)); } //第1個節點做爲根節點
        root = list.get(0); //構建二叉樹
        for (int i=0;i<list.size()/2;i++){ //父節點位置爲i,左子節點位置爲i*2+1
            if (i*2+1<list.size()){ list.get(i).setLChild(list.get(i*2+1)); } //父節點位置爲i,左子節點位置爲i*2+2
            if (i*2+2<list.size()){ list.get(i).setRChild(list.get(i*2+2)); } } } }

4、二叉樹的遍歷

一、前序遍歷
//前序遍歷(遞歸)
public void preOrder_Recursive(BinaryTree root){ if (root!=null){ System.out.print(" "+root.getData()); preOrder_Recursive(root.getLChild()); preOrder_Recursive(root.getRChild()); } }
二、中序遍歷
//中序遍歷(遞歸)
public void inOrder_Recursive(BinaryTree root){ if (root!=null){ inOrder_Recursive(root.getLChild()); System.out.print(" "+root.getData()); inOrder_Recursive(root.getRChild()); } }
三、後序遍歷
//後序遍歷(遞歸)
public void postOrder_Recursive(BinaryTree root){ if (root!=null){ postOrder_Recursive(root.getLChild()); postOrder_Recursive(root.getRChild()); System.out.print(" "+root.getData()); } }
四、層次遍歷
//層次遍歷
public void levelOrder(BinaryTree root){ //當前節點
    BinaryTree current = null; //建立隊列用於臨時存放節點
    LinkedList<BinaryTree> queue = new LinkedList<BinaryTree>(); if (root!=null){ //根節點入隊
 queue.offer(root); } while(!queue.isEmpty()){ //出隊隊頭節點
        current = queue.poll(); System.out.print(" "+current.getData()); //如有左子節點,則將其入隊
        if (current.getLChild()!=null){ queue.offer(current.getLChild()); } //如有右子節點,則將其入隊
        if (current.getRChild()!=null){ queue.offer(current.getRChild()); } } }
5、二叉樹的視圖
一、左視圖
//左視圖
public void leftView(BinaryTree root){ //當前節點
    BinaryTree current = null; //建立隊列用於臨時存放節點
    LinkedList<BinaryTree> queue = new LinkedList<BinaryTree>(); if (root!=null){ //根節點入隊
 queue.offer(root); System.out.print(" "+root.getData()); } while(!queue.isEmpty()){ int size = queue.size(); while(size>0) { //出隊隊頭節點
            current = queue.poll(); //如有左子節點,則將其入隊
            if (current.getLChild() != null) { queue.offer(current.getLChild()); } //如有右子節點,則將其入隊
            if (current.getRChild() != null) { queue.offer(current.getRChild()); } size--; //size==0時,隊列中第1個節點爲下一層右邊第1個節點
            if (size==0 && queue.size()>0){ System.out.print(" "+queue.getFirst().getData()); } } } }
二、右視圖
//右視圖
public void rightView(BinaryTree root){ //當前節點
    BinaryTree current = null; //建立隊列用於臨時存放節點
    LinkedList<BinaryTree> queue = new LinkedList<BinaryTree>(); if (root!=null){ //根節點入隊
 queue.offer(root); System.out.print(" "+root.getData()); } while(!queue.isEmpty()){ int size = queue.size(); while(size>0) { //出隊隊頭節點
            current = queue.poll(); //如有右子節點,則將其入隊
            if (current.getRChild() != null) { queue.offer(current.getRChild()); } //如有左子節點,則將其入隊
            if (current.getLChild() != null) { queue.offer(current.getLChild()); } size--; //size==0時,隊列中第1個節點爲下一層左邊第1個節點
            if (size==0 && queue.size()>0){ System.out.print(" "+queue.getFirst().getData()); } } } }
相關文章
相關標籤/搜索