【Java資料結構】二叉樹
阿新 • • 發佈:2021-11-18
【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());
}
}
}