樹(Tree): n(n≥0)個結點構成的有限集合。對於任一棵非空樹(n> 0),它具備以下性質:1、樹中有一個稱為"根(Root)"的特殊結點;2、其余結點可分為m(m>0)個互不相交的有限集,其 中每個集合本身又是一棵樹,稱為原來樹的" 子樹(SubTree)"
子樹是不相交的;除了根結點外,每個結點有且僅有一個父結點;一棵N個結點的樹有N-1條邊。
一、樹的一些基本術語
1、 結點的度(Degree): 子樹的個數,也就是,結點有幾條邊,度就是幾;
2、 樹的度:樹的所有結點中最大的度數;
3、 葉結點:度為0的結點;
4、 父結點:有子樹的結點,是其子樹的根結點的父結點;
5、 子結點:若A結點是B結點的父結點,B結點是A結點的子結點,也稱孩子結點;
6、 兄弟結點:具有同一父結點的各結點,彼此是兄弟結點;
7、 路徑:從結點n1到nk的路徑,為一 個結點序列n1 , n2 ,… , nk , ni,是 ni+1的父結 點;
8、 路徑長度:路徑所包含邊的個數為路徑的長度;
9、 祖先結點:沿樹根到某一結點路徑上的所有結點都是這個結點的祖先結點;
10、子孫結點:某一結點的子樹中的所有結點是這個結點的子孫;
11、結點的層次:規定根結點在1層, 其它任一結點的層數是其父結點的層數加1;
12、樹的深度:樹中所有結點中的最大層次;
二、樹的深度與高度
深度是從根結點向下,高度是某結點向下,到某個葉結點最長簡單路徑中邊的條數。對於整棵樹來說,最深的葉結點的深度就是樹的深度,樹根的高度就是樹的高度,這樣樹的高度和深度是相等的。對於樹中相同深度的每個結點來說,它們的高度不一定相同,這取決於每個結點下面的葉結點的深度。
三、樹的結點數 = 邊+1,即一個有N結點的的樹有N-1條邊。
1、已知一棵度為4的樹中,其度為0、1、2、3的結點數分別為14、4、3、2,求該樹的結點總數n和度為4的結點個數,並給出推導過程。
1.) 設度為4的結點為x,那么,(14+4+3+2) + x == (1*4+2*3+3*2+4*x) + 1,x為2,結點總數為:(14+4+3+2) + 2 == 25
2.) n0 = 1 + n2 + 2 * n3 + 3*n4;14 = 1 + 3 + 2*2 + 3*n4,n4為2,結點總數為:(14+4+3+2) + 2 == 25
2、在一棵度為3的樹中,度為3的節點個數為2,度為2的節點個數為1,則度為0的節點個數是多少?請給出求解過程。
n0+n1+n2+n3-1 == 0*n0 + 1*n1 + 2*n2 + 3*n3 ;n0 = 1 + n2 + 2 * n3;代入題目給出的條件,n0 = 1+1+2*2 = 6
這種樹的形狀是多樣的,但是不影響計算結果,與度為1的條件無關。
四、普通樹(General Trees),普通樹的兄弟結點數目是不受限制的,森林是由一顆或多顆樹組成的集合。
1、普通樹的實現,結點及邊的存儲和計算,兩種方式,一種是基於數組,一種是基於鏈表。
基於數組的實現,采取父指針數組(Parent pointer Array)的存儲方法,先定義一個數組存儲每一個結點,這樣每個結點都有一個序號,再定義一個整數的數組存儲結點父結點的序號(樹根是沒有父親的,可以設置成一個特殊的值)。采取父指針數組也可以實現多顆樹(森林)的存儲,只是根結點不止一個。
基於鏈表的實現,是采取左兒子右兄弟的存儲方法, 森林是每一顆普通樹采取左兒子右兄弟實現,然后把每棵樹的樹根右兄弟的方式連接起來。
2、普通樹的遍歷,普通樹主要有先根遍歷和后根遍歷;
先根遍歷:若樹非空,則先訪問根結點,再按照從左到右的順序遍歷根結點的每一棵子樹;普通樹的先根遍歷與這棵樹對應的二叉樹的先序遍歷相同;
后根遍歷:若樹非空,則按照從左到右的順序遍歷根結點的每一棵子樹,之后再訪問根結點;普通樹的后根遍歷與這棵樹對應的二叉樹的中序遍歷相同。
3、森林的遍歷,只有二叉樹森林才有中序遍歷與完全二叉樹中序遍歷相同,普通的樹構成的森林是不存在中序遍歷;森林的先根遍歷與二叉樹的先序遍歷相同,森林的后根遍歷與二叉樹的中序遍歷相同;
森林,樹,二叉樹可以相互轉換
五、二叉樹:度為2的樹;采取兒子兄弟法,可以把普通樹改為二叉樹
六、二叉樹結點定義
1 typedef struct TNode *Position; 2 typedef Position BinTree; /* 二叉樹類型 */ 3 struct TNode{ /* 樹結點定義 */ 4 ElementType Data; /* 結點數據 */ 5 BinTree Left; /* 指向左子樹 */ 6 BinTree Right; /* 指向右子樹 */ 7 };