树的定义:
树是n个结点的有限集。在任意一个非空的树中:(1)有且仅有一个特定的称为根的结点;(2)其余结点可以分成m个互不相交的子集,其中每一个子集又是一个树,称为子树。
结点的度:
结点拥有的子树的个数
树的度:
树中各结点的度的最大值
树的结点之间的关系:
结点的子树的根称为该结点的孩子,此结点就是孩子的双亲;同一个双亲的孩子称为兄弟;结点的祖先是从根节点到该结点所经过的所有结点;结点的子孙是以此结点为根的子树的子树的任一结点;双亲在同一层的结点称为堂兄弟;树中结点的最大层次称为树的深度;
有序树:树中结点各子树看成是从左到右有次序的,不能互换的
森林:互不相交的m个子树的集合
树的存储结构
(一)双亲表示法
树中每个结点除了表示自己还要附加一个指示器来指示双亲结点在数组中的位置
其中data是数据域,存储结点的数据信息。parent是指针域,存储双亲在数组中的下标
/*树的双亲表示法结点结构定义*/
#define MAX_TREE_SIZE 100
typedef int TElemType; /*结点的数据类型*/
typedef struct PTNode /*结点结构*/
{
TElemType data;
int parent;
}PTNode;
typedef struct /*树结构*/
{
PTNode nodes[MAX_TREE_SIZE];
int r, n;
}PTree;
(二)树的孩子表示法
方法:把每个结点的孩子结点排列起来,用单链表存储,这样有n个结点就有n个链表,如果是叶子结点则此单链表为空。然后n个结点又组成一个线性表,采用顺序存储结构,存放进一个一维数组。
为此要设计两种结点结构:
一是表头结点数组的表头结点
data是数据域,存储结点的数据信息,firstchild是指针域,存储该结点的孩子链表的头指针
二是孩子链表的孩子结点
child是数据域,用来存储该结点在数组中的下标,next是指针域,用来指向下一个孩子。
/*树的孩子表示法结构定义*/
#define MAX_TREE_SIZE 100
typedef struct CTNode /*孩子结点*/
{
int child;
struct CTNode *next;
}*ChildPtr;
typedef struct /*表头结点*/
{
TelemType data;
ChildPtr firstchild;
}CTBox;
typedef struct /*树*/
{
CTBox nodes[MAX_TREE_SIZE];
int r, n; /*根的位置和结点数*/
}CTree;
(三)孩子兄弟表示法
任意一棵树,它的结点的第一个孩子是唯一的,它的右兄弟如果存在也是唯一的。因此,我们设置两个指针,分别指向该结点的第一个孩子和此结点的右兄弟。
data是数据域,存储该结点的信息,firstchild是指针域,存储第一个孩子的下标,rightsib也是指针域,存储该结点右兄弟的下标。
/*树的孩子兄弟表示法结构定义*/
typedef struct CSNode
{
TELemType data;
struct CSNode *firstchild, *rightsib;
}CSNode, *CSTree;