一對多的數據結構:樹、
樹(Tree)是n(n>=0)個結點(數據元素)的有限集。在任意一棵非空樹中:
–有且僅有一個特定的稱爲根(Root)的結點;
–當n>1時,其餘結點可分爲m(m>0)個互不相交的有限集T1、T2、...、Tm,其中每一個集合本身又是一棵樹,並且稱爲根的子樹。
•注意下:
–n>0時,根結點是唯一的,堅決不可能存在多個根結點。
–m>0時,子樹的個數是沒有限制的,但它們互相是一定不會相交的。
結點:數據元素+若干指向子樹的分支
結點的度:結點的子樹個數(後繼個數);
樹的度:樹中各結點的度的最大值;
葉結點(終端結點):度爲零的結點;
分支結點(非終端結點):度大於零的結點;
結點的子樹的根稱爲結點的孩子(Child),相應的,該結點稱爲孩子的雙親(Parent),同一雙親的孩子之間互稱爲兄弟(Sibling)。
結點的祖先是從根到該結點所經分支上的所有結點。
結點的層次(Level)從根開始定一起,根爲第一層,根的孩子爲第二層。
其雙親在同一層的結點互爲堂兄弟。
樹中結點的最大層次稱爲樹的深度(Depth)或高度。
樹的存儲結構
要存儲樹,不能用簡單的順序存儲結構和鏈式存儲結構,需要考慮到要考慮到雙親、孩子、兄弟之間的關係。
- 雙親表示法:以雙親作爲索引的關鍵詞的一種存儲方式。
假設以一組連續空間存儲樹的結點,同時在每個結點中,附設一個指示其雙親結點在數組中位置的元素。
// 樹的雙親表示法結點結構定義
#define MAX_TREE_SIZE 100
typedef int ElemType;
typedef struct PTNode
{
ElemType data; // 結點數據
int parent; // 雙親位置
}PTNode;
typedef struct
{
PTNode nodes[MAX_TREE_SIZE];
int r; // 根的位置
int n; // 結點數目
}PTree;
這樣的存儲結構,我們可以根據某結點的parent指針找到它的雙親結點,所用的時間複雜度是O(1),索引到parent的值爲-1時,表示找到了樹結點的根。 但是如果想知道結點的孩子是什麼就需要遍歷整個數組,或者改變一下結構帶上孩子的位置。
- 帶雙親的孩子鏈表示法:樹中每個結點可能有多棵子樹,可以考慮用多重鏈表來實現。
#include<stdio.h>
#define MAX_TREE_SIZE 100
//孩子結點
typedef char ElemType;
typedef struct CTNode
{
int child; //孩子結點的下標
struct CTNode *next; //指向下一個孩子結點的指針
}*ChildPter;
//表頭結構
typedef struct
{
ElemType data; //存放在樹中結點的數據
int parent; //存放雙親的下標
ChildPtr firstchild; //指向第一個孩子的指針
}CTBox;
//樹結構
typedef struct
{
CTBox nodes[MAX_TREE_SIZE]; //結點數組
int r,n;
}
- 孩子兄弟表示法(二叉樹表示法,二叉鏈表表示法)
// ----- 樹的二叉鏈表(孩子-兄弟)存儲表示 -----
typedef struct CSNode {
ElemType data;
struct CSNode *fch, *nsib;
}CSNode, *CSTree;