1.樹的定義
樹(Tree)是n(n≥0)個有限數據元素的集合。當n=0 時,稱這棵樹爲空樹。在一棵非樹T 中:
(1)有一個特殊的數據元素稱爲樹的根結點,根結點沒有前驅結點。
(2)若n>1,除根結點之外的其餘數據元素被分成m(m>0)個互不相交的集合T1,T2,…,Tm,其中每一個集合Ti(1≤i≤m)本身又是一棵樹。樹T1,T2,…,Tm 稱爲這個根結點的子樹。
可以看出,樹是一種一對多的概念,在樹的定義中用了遞歸概念,即用樹來定義樹。因此,樹結構的算法類同於二叉樹結構的算法,也可以使用遞歸方法。
樹的定義還可形式化的描述爲二元組的形式:
當樹爲空樹時,D=Φ;當樹T 不爲空樹時有:
樹定義的形式化,主要用於樹的理論描述。
圖7.1(a)是一棵具有9 個結點的樹,即T={A,B,C,…,H,I},結點A 爲樹T 的根結點,除根結點A 之外的其餘結點分爲兩個不相交的集合: T1={B,D,E,F,H,I}和T2={C,G},T1 和T2 構成了結點A 的兩棵子樹,T1 和T2 本身也分別是一棵樹。例如,子樹T1 的根結點爲B,其餘結點又分爲兩個不相交的集合:T11={D},T12={E,H,I}和T13={F}。
T11、T12 和T13 構成了子樹T1 的根結點B 的三棵子樹。如此可繼續向下分爲更小的子樹,直到每棵子樹只有一個根結點爲止。
從樹的定義和圖7.1(a)的示例可以看出,樹具有下面兩個特點:
(1)樹的根結點沒有前驅結點,除根結點之外的所有結點有且只有一個前驅結點。
(2)樹中所有結點可以有零個或多個後繼結點。
由此特點可知,圖7.1(b)、(c)、(d)所示的都不是樹結構(互不相交)。
2.樹的儲存結構
儲存結構分爲順序儲存結構和鏈式儲存結構。
順序儲存結構是用一段連續的地址儲存數據元素,一般通過數組表示。
鏈式儲存結構是通過指針來鏈接到下一個元素。
對於樹的表示需要結合兩者。
一雙親表示法
我們以一組連續的空間儲存樹的節點,同時在節點中附帶一個指示器標示雙親在鏈表中的位置。
這種儲存結構的好處是,我們能夠很容易的找到一個節點的父節點,O(1),但是想找到一個節點的子節點需要遍歷整個鏈表。
二孩子表示法
每個節點有多個指針域分別指向一顆子樹的根節點。我們把它叫做多重鏈表表示法。
但是每個節點的度是不一樣,給這種表示法帶來了一定的困難。
有兩種方案解決這個問題:
第一種,指針域的個數等於樹的度,即各個節點度的最大值。
第二種,每個節點指針域的個數等於該節點的度,並設立一個專門的域來保存節點的度。
第一種方法對於樹中度差別很大的情況下極度的浪費了空間。
第二種方法雖然克服了浪費空間的問題,但是各個鏈表的長度不一樣,這給操作帶來一定的困難。
這就引出了我們的孩子表示法。
每個節點的孩子節點以單鏈表的形式儲存起來,n個頭指針又組成一個鏈表,以順序表示法儲存起來。
三孩子兄弟表示法
任意一棵樹,它的節點的第一個孩子節點存在一定是唯一的,它的右兄弟節點存在也一定是唯一的。
我們可以對任意一棵樹進行改造,它很容易的把任意棵樹變成二叉樹。