1. 程式人生 > 其它 >【Java資料結構】二叉樹

【Java資料結構】二叉樹

【Java資料結構】二叉樹

一、二叉樹的邏輯結構

1、二叉樹的定義

2、特殊的二叉樹

①滿二叉樹

  • 如果一顆二叉樹中,所有分支結點都存在左子樹和右子樹,並且所有葉子都在同一層上,則這樣的二叉樹稱為滿二叉樹。
    • 葉子只能出現在最下一層
    • 只有度為0和度為2的結點

②完全二叉樹

  • 如果一顆二叉樹中,除了最底層結點可能沒有填滿之外,其餘每層結點樹都打到最大值,並且最下面一層的結點都集中在該層最左邊的若干位置
  • 堆就是一顆完全二叉樹,同時保證父子結點的順序關係。

演算法基礎三:分治演算法---基於二叉堆的優先佇列 - DarkerG - 部落格園 (cnblogs.com)

③二叉搜尋樹BST

Binary Search Tree

  • 二叉搜尋樹是由數值的數,二叉搜尋樹是一個有序樹。
    • 若它的左子樹不為空,則左子樹上所有結點的值均小於它的根節點的值。
    • 若它的右子樹不為空,則右子樹上所有結點的值均大於它的根節點的值。
    • 它的左、右子樹也分別是二叉排序樹。

④平衡二叉搜尋樹AVL

  • AVL(Adelson-Velsky and Landis)樹
    • 它是一棵空樹或者它的左右兩個子樹的高度差的絕對值不超過1,並且左右兩個子樹都是一顆平衡二叉樹。

⑤霍夫曼樹

⑥紅黑樹R-B Tree

⑦B-Tree(B-樹或者B樹)

⑧B+ Tree(B+樹)

二、二叉樹的遍歷操作定義

1、遍歷的種類

  • 前中後序遍歷的操作
  • 層序遍歷:
    • 從二叉樹的根節點開始,從上至下逐層遍歷,同一層按照從左到右的順序對結點逐個訪問。

2、遍歷操作舉例

  • 前序遍歷:ABDGCEF
  • 中序遍歷:DGBAECF
  • 後序遍歷:GDBEFCA
  • 層序遍歷:ABCDEFG

確定一顆二叉樹,任何遍歷操作都是唯一的。但是根據任一遍歷操作卻不能確定一棵二叉樹

  • 可以通過前序遍歷和中序遍歷可以唯一確定這棵二叉樹
  • 可以通過後序遍歷和中序遍歷可以唯一確定一棵二叉樹

三、二叉樹的儲存結構及實現

1、二叉樹的Java介面定義

public interface BinaryTreeInterface<T>{
    public void preOrder();			//前序
    public void inOrder();
    public void postOrder();
    public void levelOrder();
    //根據前序遍歷序列構建二叉樹
    public void createBiTree(SequentialList<T> treeElemnt);
}

2、順序儲存結構

圖示

程式碼

public class SequentialTree<T> implements BinaryTreeInterface{
    protected T[] seqTree;	//二叉樹順序儲存陣列
    private final static int TREE_MAX_SIZE=100;//儲存容量
    //成員函式實現二叉樹介面函式
}

特點

  • 浪費儲存空間,最壞的情況就是右斜樹,一棵深度為k的右斜樹只有k個結點,卻需要分配2^k-1個儲存單元。事實上,二叉樹的順序儲存結構一般僅適合儲存完全二叉樹。

3、二叉連結串列

public class BiNode<T>{
    private T data;		//定義結點泛型資料域
    private BiNode<T> lChild,rChild;	//定義結點左、右孩子引用域
    public BiNode(T element){//構造資料域為element值的結點
        this.data=element;
    }
    public T getDate(){return data;}//獲取資料域
    public void setDate(T data) {this.data=data;}
    public BiNode<T> getlChild(){return lChild;}
    public BiNode<T> setlChild(){this.lChild = lChild;}
    public BiNode<T> getrChild(){return rChild;}
    public BiNode<T> setrChild(){this.rChild = rChild;}
}

圖示

二叉連結串列的實現

​ 在BinaryTree類中,通過定義BiNode型別根節點變數root實現二叉連結串列儲存結構。BinaryTree類實現BinaryTreeInterface介面定義的方法。

public class BinaryTree<T> implements BinaryTreeInterface{
    protected BiNode<T> root;
    //成員函式實現二叉樹介面演算法
}
  • 二叉樹初始化(BinaryTree)---構造器
public BinaryTree(){
    root=null;
}
  • 前序遍歷(preOrder)
    • 遞迴演算法
public void preOrder(){//前序遍歷入口
    preOrder(root);
}
private void preOrder(BiNode node){//前序遍歷遞迴實現
    if(node==null){
        return;
    }else{
        System.out.print(node.getData()+" ");//訪問當前節點的資料域
        preOrder(node.getlChild());	//前序遞迴遍歷node的左子樹
        preOrder(node.getrChild());	//前序遞迴遍歷node的右子樹
    }
}
  • 中序遍歷(inOrder)
  • 後序遍歷(postOrder)
  • 層序遍歷(levelOrder)
  • 演算法的虛擬碼描述
  • 演算法實現
public void levelOrder(){
    QueueInterface<BiNode> queue = new LinkedQueue<BiNode>();
    if(root==null){
        return;
    }else{
        queue.enQueue(root);		//根引用入隊
        while(!queue.isEmpty()){
            BiNode tempNode = queue.deQueue();//出隊
            System.out.print(tempNode.getData()+" ");//輸出結點資料域
            if(tempNode.getlChild() !=null)			//結點非空左孩子入隊
                queue.enQueue(tempNode.getlChild());
            if(tempNode.getrChild() !=null)			//結點非空右孩子入隊
                queue.enQueue(tempNode.getrChild());
        }
    }
}