樹的定義和樹的三種存儲結構


秩也就是他的高度;

一、樹的定義

1.樹的定義

樹(Tree)是n(n>=0)個結點的有限集。n=0時稱為空樹。在任意一顆非空樹中:

  1. 有且僅有一個特定的稱為根(root)的結點
  2. 當n>1時,其余結點可分為m(m>0)個互補交互的有限集T1、T2...Tm,其中每一個集合本身又是一棵樹,並稱為根的子樹(SubTree)

    <p>Tree</p>
    </li>
    

2.樹的特點

  • n>0時,根節點是唯一的,不可能存在多個根節點。數據結構中的樹只有一個根節點。
  • m>0時,子樹的個數沒有限制,但他們一定是互不相交的

3.結點的分類

  • 結點:樹的結點包含一個數據元素和若干指向其子樹的分支
  • 結點的度(Degree):結點擁有的子樹。
  • 葉子結點(Leaf)/終端結點:度為0的結點。
  • 分支結點/非終端結點:度不為0的結點。
  • 內部結點:除根節點以外,分支結點也稱為內部結點。
  • 樹的度:樹內各結點的度的最大值

    <p>結點的分類</p>
    </li>
    

4.結點之間的關系

  • 孩子(Child)和雙親(Parent):結點的子樹的根,相應的,該結點稱為孩子的雙親。(注意是雙親,不是單親)
  • 兄弟(sibling):同一個雙親的孩子之間互稱兄弟。
  • 結點的祖先:從根結點到該結點所經過分支上的所有結點
  • 子孫:以某結點為根的子樹中的任一結點都稱為該節點的子孫。
  • 無序樹和有序樹:如果將樹中結點的各子樹看成從左至右是有次序的,不能互換的,則稱該數為有序樹,否則為無序樹。
  • 森林(fores):m(m>=0)棵互不相較的樹的集合。

二、樹的存儲結構

對於存儲結構,可能會聯想到前面的順序存儲和鏈式存儲結構。但是對於數這種可能會有很多孩子的特殊數據結構,只用順序存儲結構或者鏈式存儲結構很那實現,那么可以將這兩者結合,產生主要的三種存儲結構表示法:雙親表示法、孩子表示法、孩子兄弟表示法。

1.雙親表示法

雙親表示法定義

假設以一組連續空間存儲數的結點,同時在每個結點中,附設一個指示器指示其雙親結點到鏈表中的位置

雙親表示的結點結構

data(數據域) parent(指針域)
存儲結點的數據信息 存儲該結點的雙親所在數組中的下標

代碼實現雙親表示法


   
   
  
  
          
  1. /* 樹的雙親表法結點結構定義*/
  2. #define MAX_TREE_SIZE 100
  3. typedef int ElemeType;
  4. typedef struct PTNode{ // 結點結構
  5. ElemeType data; //結點數據
  6. int parent; // 雙親位置
  7. }PTNode;
  8. typedef struct { // 樹結構
  9. PTNode nodes[MAX_TREE_SIZE]; // 結點數組
  10. int r; // 根的位置
  11. int n; // 結點數
  12. }PTree;

雙親表示法的特點

  • 由於根結點是沒有雙親的,約定根結點的位置位置域為-1.
  • 根據結點的parent指針很容易找到它的雙親結點。所用時間復雜度為O(1),直到parent為-1時,表示找到了樹結點的根。
  • 缺點:如果要找到孩子結點,需要遍歷整個結構才行

2.孩子表示法

孩子表示法定義

把每個結點的孩子結點排列起來,以單鏈表作為存儲結構,則n個結點有n個孩子鏈表,如果是葉子結點則此單鏈表為空。然后n個頭指針又組成一個線性表,采用順序存儲結構,存放進一個一維數組中。

孩子表示法

 

孩子表示法的結點結構

孩子表示法有兩種結點結構:孩子鏈表的孩子結點表頭數組的表頭結點

  • 孩子鏈表的孩子結點
child(數據域) next(指針域)
存儲某個結點在表頭數組中的下標 存儲指向某結點的下一個孩子結點的指針
  • 表頭數組的表頭結點
data(數據域) firstchild(頭指針域)
存儲某個結點的數據信息 存儲該結點的孩子鏈表的頭指針

代碼實現孩子表示法


   
   
  
  
          
  1. /* 樹的孩子表示法結構定義*/
  2. #define MAX_TREE_SIZE 100
  3. typedef int ElemeType;
  4. typedef struct CTNode{ // 孩子結點
  5. int child; // 孩子結點的下標
  6. struct CTNode * next; // 指向下一結點的指針
  7. }*ChildPtr;
  8. typedef struct { // 表頭結構
  9. ElemeType data; // 存放在數中的結點數據
  10. ChildPtr firstchild; // 指向第一個孩子的指針
  11. } CTBox;
  12. typedef struct { // 樹結構
  13. CTBox nodes[MAX_TREE_SIZE]; // 結點數組
  14. int r; // 根的位置
  15. int n; // 結點樹
  16. } CTree;

雙親孩子表示法定義

對於孩子表示法,查找某個結點的某個孩子,或者找某個結點的兄弟,只需要查找這個結點的孩子單鏈表即可。但是當要尋找某個結點的雙親時,就不是那么方便了。所以可以將雙親表示法和孩子表示法結合,形成雙親孩子表示法


show code

 


   
   
  
  
          
  1. /* 樹的雙親孩子表示法結構定義*/
  2. #define MAX_TREE_SIZE 100
  3. typedef int ElemeType;
  4. typedef struct CTNode{ // 孩子結點
  5. int child; // 孩子結點的下標
  6. struct CTNode * next; // 指向下一結點的指針
  7. }*ChildPtr;
  8. typedef struct { // 表頭結構
  9. ElemeType data; // 存放在數中的結點數據
  10. int parent; // 存放雙親的下標
  11. ChildPtr firstchild; // 指向第一個孩子的指針
  12. } CTBox;
  13. typedef struct { // 樹結構
  14. CTBox nodes[MAX_TREE_SIZE]; // 結點數組
  15. int r; // 根的位置
  16. int n; // 結點樹
  17. } CTree;

3.孩子兄弟表示法

孩子兄弟表示法定義

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

孩子兄弟表示法的結點結構

data(數據域) firstchild(指針域) rightsib(指針域)
存儲結點的數據信息 存儲該結點的第一個孩子的存儲地址 存儲該結點的右兄弟結點的存儲地址

代碼實現孩子兄弟表示法


   
   
  
  
          
  1. /* 樹的孩子兄弟表示法結構定義*/
  2. #define MAX_TREE_SIZE 100
  3. typedef int ElemeType;
  4. typedef struct CSNode{
  5. ElemeType data;
  6. struct CSNode * firstchild;
  7. struct CSNode * rightsib;
  8. }CSNode, *CSTree;


 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM