6.2树的定义:
1.树是n个结点的有限集,n=0时称为空树
2.有且仅有一个特定的根
3.子树的个数没有限制,但他们一定是不相交,如下图,就不是子树
4.结点拥有的子树数称为结点的度。度为0的结点称为叶节点;度不为0的结点称为分支结点。除根节点之外,分支节点也称内部结点;树的度是树内各结点的度的最大值,如下图
6.3结点间的关系:
1.结点的祖先是从根到该结点所经分支上的所有结点 对于H而言ABD都为他的祖先。其他各种关系见下图
2.树的相关概念,如下图:
3.树与线性表之间的差别,如下图:
6.3树的抽象数据类型,如下图:
6.4树的存储结构=== 双亲表示法
1.除了根节点啊外,其余每个结点,它不一定有孩子,但是一定有且仅有一个双亲
2.以一组连续空间存储树的结点,同时在每个结点中,附设一个指示器指示其双亲结点在数组中的位置,结构如下:
data parent //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; //根的位置和结点数
}
上面的代码对应下图:
改进1:在结点中加入左孩子:
改进2:在结点中加入有兄弟:
6.4.2孩子表示法:由于树中每个结点可能有多棵子树,可以考虑用多重链表,即每个结点有多个指针域,其中每个指针指向一颗子树的根结点,我们把这种方法叫做多重链表法:如下图,有两种方案:
方案一:
指针域的个数就是树的度,树的度是树中各个结点度的最大值,结构如下图:
方案2:
每个结点指针域的个数等于该结点的度,专门取一个位置来存储结点指针域的个数,如下图:
重点是如下:
孩子表示法:把每个结点的孩子结点排列起来,以单链表做存储结构,则n个结点有n个孩子链表,如果是叶子结点则此单链表为空。然后n个头指针有组成一个线性表,采用顺序存储结构,存放进一个维数组中,如图
//树的孩子表示法结构定义:
#define MAX_TREE_SIZE 100
typedef struct CTNode //孩子结点
{
int chile; //数据域:用来存储某个结点在表头数组中的下标
struct CTNode *next; //指针域:存储指向某结点另一个孩子结点的指针
}*ChildPtr;
typedef struct
{
TElemType data; //存储某结点的数据信息
ChildPtr firstchild; //存储该结点的孩子链表的头指针
}CTBox;
typedef struct //树结构
{
CTBox nodes[MAX_TREE_SIZE]; //结点数组
int r,n; //根的位置和结点数
}
双亲表示法和孩子表示法综合,如下图:
6.4.3孩子兄弟表示法:
结点结构如下图:
firstchild 为指针域,存储该结点的第一个孩子存储地址