秩也就是他的高度;
一、樹的定義
1.樹的定義
樹(Tree)是n(n>=0)個結點的有限集。n=0時稱為空樹。在任意一顆非空樹中:
- 有且僅有一個特定的稱為根(root)的結點;
- 當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(指針域) |
---|---|
存儲結點的數據信息 | 存儲該結點的雙親所在數組中的下標 |
代碼實現雙親表示法
-
/* 樹的雙親表法結點結構定義*/
-
#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;