樹是n個結點的有限集。n=0時稱爲空樹。在任意一棵非空樹中:
1.有且僅有一個特定的稱爲根結點
2.n > 1時,其餘結點可分爲m個互不相交的有限集T1、T2、......Tm,其中每個集合本身有時一棵樹,並且稱爲根的子樹。如下圖:
子樹T1,T2是上面的子樹
關於樹的定義要注意以下兩點:
1.n>0時根結點是唯一的。
2.m>0時,子樹的個數沒有限制,但它們一定是互不相交的
結點擁有的子樹稱爲結點的度。度爲0的結點稱爲葉結點或者終端結點;度不爲0的結點稱爲非終端結點或分支結點。除根結點外,分支結點也稱爲內部結點。樹的度是樹內各結點的度的最大值。
結點的子樹的根稱爲該結點的孩子,相應的,該結點稱爲孩子的雙親。同一個雙親的孩子之間互稱兄弟。結點的祖先是從根到該結點所經分支上的所有結點。
以某結點爲根的子樹中的任一結點都稱爲該結點的子孫。
樹的其他相關概念:
結點的層次從根開始定義起,根爲第一層,根的孩子爲第二層。樹中結點的最大層次稱爲樹的深度或高度。上面示意圖樹的深度是4。
如果將樹中結點的各子樹看成從左至右是有次序的,不能互換的,則稱爲該樹是有序樹,否則稱爲無序樹。
森林是m棵互不相交的樹的集合。
線性結構與樹結構的不同:
線性結構:第一個數據元素沒有前驅,最後一個數據元素沒有後繼,中間元素一個前驅一個後繼
樹結構:
根結點無雙親,唯一;葉結點無孩子,可以多個;中間結點:一個雙親多個孩子
樹的存儲結構:
1.雙親表示法:
在每個結點中,設一個指示器指示其雙親結點到鏈表中的位置。如下圖:
data是數據域,parent是指針域。
下標 | data | parent |
0 | A | -1 |
1 | B | 0 |
2 | C | 0 |
3 | D | 1 |
4 | E | 2 |
5 | F | 2 |
6 | G | 3 |
7 | H | 3 |
8 | I | 3 |
9 | J | 4 |
2.孩子表示法:
每個結點有多個指針域,其中每個指針指向一棵子樹的根結點,這種方法叫做多重鏈表表示法。有兩種方案來解決孩子個數不同的問題。
方案一:一種是指針域的個數等於樹的度
顯然這種方法浪費空間
方案二:一種是指針域的個數等於樹的度,專門取一個位置來存儲結點指針域的個數
這種方法克服了浪費空間的缺點,空間利用率提高了,但是在時間上的損耗變多了。
以上兩種方法都有一定的缺點,而孩子表示法則沒有上述兩種方法的缺點。孩子表示法是指把每個結點的孩子結點排列起來,以單鏈表作存儲結構,則n個結點有n個孩子鏈表,如果是葉子結點則此單鏈表爲空。然後n個頭指針又組成一個線性表,採用順序存儲結構,存放進一個一維數組中。如下圖:
孩子法的結構定義代碼:
3.孩子兄弟表示法:
任意一棵樹,它的結點的第一個孩子如果存在唯一的,它的有兄弟如果存在也是唯一的。因此我們設置兩個指針,分別指向該結點的 第一個孩子和此結點的右兄弟。結點結構如下表:
data | firstchild | rightsib |
示意圖如下: