樹的定義和樹的三種儲存結構
阿新 • • 發佈:2018-11-04
秩也就是他的高度;
一、樹的定義
1.樹的定義
樹(Tree)是n(n>=0)個結點的有限集。n=0時稱為空樹。在任意一顆非空樹中:
- 有且僅有一個特定的稱為根(root)的結點;
- 當n>1時,其餘結點可分為m(m>0)個互補互動的有限集T1、T2...Tm,其中每一個集合本身又是一棵樹,並稱為根的子樹(SubTree)。
Tree
2.樹的特點
- n>0時,根節點是唯一的,不可能存在多個根節點。資料結構中的樹只有一個根節點。
- m>0時,子樹的個數沒有限制,但他們一定是互不相交的。
3.結點的分類
- 結點:樹的結點包含一個數據元素和若干指向其子樹的分支
- 結點的度(Degree):結點擁有的子樹。
- 葉子結點(Leaf)/終端結點:度為0的結點。
- 分支結點/非終端結點:度不為0的結點。
- 內部結點:除根節點以外,分支結點也稱為內部結點。
- 樹的度:樹內各結點的度的最大值。
結點的分類
4.結點之間的關係
- 孩子(Child)和雙親(Parent):結點的子樹的根,相應的,該結點稱為孩子的雙親。(注意是雙親,不是單親)
- 兄弟(sibling):同一個雙親的孩子之間互稱兄弟。
- 結點的祖先:從根結點到該結點所經過分支上的所有結點。
- 子孫:以某結點為根的子樹中的任一結點都稱為該節點的子孫。
- 無序樹和有序樹:如果將樹中結點的各子樹看成從左至右
- 森林(fores):m(m>=0)棵互不相較的樹的集合。
二、樹的儲存結構
對於儲存結構,可能會聯想到前面的順序儲存和鏈式儲存結構。但是對於數這種可能會有很多孩子的特殊資料結構,只用順序儲存結構或者鏈式儲存結構很那實現,那麼可以將這兩者結合,產生主要的三種儲存結構表示法:雙親表示法、孩子表示法、孩子兄弟表示法。
1.雙親表示法
雙親表示法定義
假設以一組連續空間儲存數的結點,同時在每個結點中,附設一個指示器指示其雙親結點到連結串列中的位置。
雙親表示的結點結構
data(資料域) | parent(指標域) |
---|---|
儲存結點的資料資訊 | 儲存該結點的雙親所在陣列中的下標 |
程式碼實現雙親表示法
/* 樹的雙親表法結點結構定義*/
#define MAX_TREE_SIZE 100
typedef int ElemeType;
typedef struct PTNode{ // 結點結構
ElemeType data; //結點資料
int parent; // 雙親位置
}PTNode;
typedef struct { // 樹結構
PTNode nodes[MAX_TREE_SIZE]; // 結點陣列
int r; // 根的位置
int n; // 結點數
}PTree;
雙親表示法的特點
- 由於根結點是沒有雙親的,約定根結點的位置位置域為-1.
- 根據結點的
parent
指標很容易找到它的雙親結點。所用時間複雜度為O(1),直到parent為-1時,表示找到了樹結點的根。 - 缺點:如果要找到孩子結點,需要遍歷整個結構才行。
2.孩子表示法
孩子表示法定義
把每個結點的孩子結點排列起來,以單鏈表作為儲存結構,則n個結點有n個孩子連結串列,如果是葉子結點則此單鏈表為空。然後n個頭指標又組成一個線性表,採用順序儲存結構,存放進一個一維陣列中。
孩子表示法
孩子表示法的結點結構
孩子表示法有兩種結點結構:孩子連結串列的孩子結點和表頭陣列的表頭結點
- 孩子連結串列的孩子結點
child(資料域) | next(指標域) |
---|---|
儲存某個結點在表頭陣列中的下標 | 儲存指向某結點的下一個孩子結點的指標 |
- 表頭陣列的表頭結點
data(資料域) | firstchild(頭指標域) |
---|---|
儲存某個結點的資料資訊 | 儲存該結點的孩子連結串列的頭指標 |
程式碼實現孩子表示法
/* 樹的孩子表示法結構定義*/
#define MAX_TREE_SIZE 100
typedef int ElemeType;
typedef struct CTNode{ // 孩子結點
int child; // 孩子結點的下標
struct CTNode * next; // 指向下一結點的指標
}*ChildPtr;
typedef struct { // 表頭結構
ElemeType data; // 存放在數中的結點資料
ChildPtr firstchild; // 指向第一個孩子的指標
}CTBox;
typedef struct { // 樹結構
CTBox nodes[MAX_TREE_SIZE]; // 結點陣列
int r; // 根的位置
int n; // 結點樹
}CTree;
雙親孩子表示法定義
對於孩子表示法,查詢某個結點的某個孩子,或者找某個結點的兄弟,只需要查詢這個結點的孩子單鏈表即可。但是當要尋找某個結點的雙親時,就不是那麼方便了。所以可以將雙親表示法和孩子表示法結合,形成雙親孩子表示法。
show code
/* 樹的雙親孩子表示法結構定義*/
#define MAX_TREE_SIZE 100
typedef int ElemeType;
typedef struct CTNode{ // 孩子結點
int child; // 孩子結點的下標
struct CTNode * next; // 指向下一結點的指標
}*ChildPtr;
typedef struct { // 表頭結構
ElemeType data; // 存放在數中的結點資料
int parent; // 存放雙親的下標
ChildPtr firstchild; // 指向第一個孩子的指標
}CTBox;
typedef struct { // 樹結構
CTBox nodes[MAX_TREE_SIZE]; // 結點陣列
int r; // 根的位置
int n; // 結點樹
}CTree;
3.孩子兄弟表示法
孩子兄弟表示法定義
任意一棵樹,它的結點的第一個孩子如果存在就是唯一的,它的右兄弟存在也是唯一的。因此,設定兩個指標,分別指向該結點的第一個孩子和此結點的右兄弟。
孩子兄弟表示法的結點結構
data(資料域) | firstchild(指標域) | rightsib(指標域) |
---|---|---|
儲存結點的資料資訊 | 儲存該結點的第一個孩子的儲存地址 | 儲存該結點的右兄弟結點的儲存地址 |
程式碼實現孩子兄弟表示法
/* 樹的孩子兄弟表示法結構定義*/
#define MAX_TREE_SIZE 100
typedef int ElemeType;
typedef struct CSNode{
ElemeType data;
struct CSNode * firstchild;
struct CSNode * rightsib;
}CSNode, *CSTree;