數據結構(9)——樹

樹的定義:
樹是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是指針域。

[cpp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. <span style="font-size:18px;">/*結點定義*/  
  2. #define MAX_TREE_SIZE 100  
  3. typedef struct PTNode  
  4. {  
  5.     int data;   //結點數據,類型根據實際情況而定  
  6.     int parent;  //雙親位置  
  7. }PTNode;  
  8. typedef struct    //樹結構  
  9. {  
  10.     PTNode nodes[MAX_TREE_SIZE];   //結點數組  
  11.     int r,n;    //根的位置和結點數  
  12. }PTree;</span>  

下標 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
當parent爲-1時,表示找到了樹的根結點


2.孩子表示法:

每個結點有多個指針域,其中每個指針指向一棵子樹的根結點,這種方法叫做多重鏈表表示法。有兩種方案來解決孩子個數不同的問題。


方案一:一種是指針域的個數等於樹的度
顯然這種方法浪費空間


方案二:一種是指針域的個數等於樹的度,專門取一個位置來存儲結點指針域的個數

這種方法克服了浪費空間的缺點,空間利用率提高了,但是在時間上的損耗變多了。


以上兩種方法都有一定的缺點,而孩子表示法則沒有上述兩種方法的缺點。孩子表示法是指把每個結點的孩子結點排列起來,以單鏈表作存儲結構,則n個結點有n個孩子鏈表,如果是葉子結點則此單鏈表爲空。然後n個頭指針又組成一個線性表,採用順序存儲結構,存放進一個一維數組中。如下圖:


孩子法的結構定義代碼:

[cpp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. <span style="font-size:18px;">#define MAX_TREE_SIZE 100  
  2. typedef struct CTNode  
  3. {  
  4.     int child;  
  5.     struct CTNode *next;  
  6. }ChildPtr;  
  7. int struct  //表頭結構  
  8. {  
  9.     int data;  
  10.     ChildPtr firstchild;  
  11. }CTBox;  
  12. typedef struct  
  13. {  
  14.     CTBox nodes[MAX_TREE_SIZE];  
  15.     int r,n;  
  16. }CTree;</span>  

3.孩子兄弟表示法:

任意一棵樹,它的結點的第一個孩子如果存在唯一的,它的有兄弟如果存在也是唯一的。因此我們設置兩個指針,分別指向該結點的 第一個孩子和此結點的右兄弟。結點結構如下表:

data firstchild rightsib
結構定義代碼如下:
[cpp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. typedef struct CSNode  
  2. {  
  3.     int data;  
  4.     struct CSNode 8firstchild,*rightsib;  
  5. }CSNode,*CSTree;  
示意圖如下:


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章