概述
樹,它是由n(n>=0)個有限節點組成一個具有層次關係的集合。當n=0時,這棵樹被稱之爲空樹。
樹它具有以下的特點:
- 每個節點有零個或多個子節點;
- 沒有父節點的節點稱爲根節點;
- 每一個非根節點有且只有一個父節點;
- 除了根節點外,每個子節點可以分爲多個不相交的子樹;
樹的相關屬性
結點的度
- 結點擁有的子樹數稱爲結點的度。
- 度爲0的結點稱爲葉子結點或終端結點,度不爲0的結點稱爲非終端結點或分支結點。
- 除根結點以外,分支結點也稱爲內部結點。
- 樹的度:一棵樹中,最大的節點的度稱爲樹的度;
層次與深度
- 節點的層次:從根開始定義起,根爲第1層,根的子節點爲第2層,以此類推;
- 樹的高度或深度:樹中節點的最大層次;
- 兄弟節點:具有相同父節點的節點互稱爲兄弟節點;
- 堂兄弟節點:雙親在同一層的節點互爲堂兄弟;
樹的分類
- 無序樹:樹中任意節點的子結點之間沒有順序關係,這種樹稱爲無序樹,也稱爲自由樹;
- 有序樹:樹中任意節點的子結點之間有順序關係,這種樹稱爲有序樹;
- 霍夫曼樹:帶權路徑最短的二叉樹稱爲哈夫曼樹或最優二叉樹;
- 二叉樹:每個節點最多含有兩個子樹的樹稱爲二叉樹;
樹的數據結構
在樹的數據結構中,簡單的數據結構不能滿足樹,所以我們需要通過順序存儲結構和鏈式存儲結構。
通常,有三種方式來表示樹的存儲結構:
- 雙親表示法
- 孩子表示法
- 孩子兄弟表示法
雙親表示法
所謂雙親表示法,在每個結點中,附設一個指示器指示其雙親結點到鏈表中的位置。
雙親表示法的的優點是找到雙親節點容易,但是找到孩子節點困難。
數據結構:
具體表示如下:
代碼定義:
/**
* 雙親表示法
*/
public class TreeNode<E> {
private int parent;
private E data;
}
孩子表示法
所謂孩子表示法,就是把每個結點的孩子結點排列起來,以單鏈表作爲存儲結構,則n個結點有n個孩子鏈表,如果是葉子結點則此單鏈表爲空,然後n個頭指針又組成一個線性表,採用順序存儲結構,存放在一個一維數組中。
使用孩子表示法,尋找孩子節點比較容易,但是找到雙親節點會非常困難。
數據結構:
具體表示如下:
代碼實現:
/**
* 頭節點
*/
public class HeadNode<E> {
private E data;
private ChildNode firstChild;
}
/**
* 孩子節點
*/
public class ChildNode<E>{
private E data;
private ChildNode next;
}
孩子兄弟表示法
任意一棵樹,它的結點的第一個孩子如果存在就是唯一的,它的右兄弟如果存在也是唯一的。因此,我們設置兩個指針,分別指向該結點的第一個孩子和此結點的右兄弟。這種數據結構稱之爲孩子兄弟表示法。
數據結構:
具體表示如下:
代碼實現如下:
public class Node<E> {
private E data;
private Node firstChild;
private Node rightBrother;
}