前言
前面我们讨论的都是一对一的线性结构,可是在现实中,还有很多一对多的情况,于是我们引出了一对多的数据结构——树。对于树的存储结构,我们要充分利用顺序存储和链式存储的特点,这里根据程杰老师的书,我们用三种不同的表示方法:
双亲表示法
孩子表示法
孩子兄弟表示法
1.树举例
先举一个树的例子:
字母前中括号表示下标
2.双亲表示法
每个结点一定有他的双亲,直接用顺序存储,如图:
-
找双亲很容易:
以一组连续空间存储树的结点,但是在每个结点中,附带一个指针域指示其双亲结点在数组中位置,根结点位置域设为-1,如表parent列 -
找结点的孩子:
增加一个结点最左侧孩子的指针域(长子域),没有就为-1,如表firstchild列 -
兄弟之间的关系,再增加一个右兄弟域,每一个结点存在右兄弟,记录下标,没有为-1,如表rightsib列所示
-
需要什么功能,怎么表示,可以由自己设置
-
定义代码
typedef struct
{
TelemType data; //结点数据
int parent; //双亲位置
} PTNode;
typedef struct
{
PTNode nodes[M]; //结点数组
int r,n;//根位置数和结点数
}
3.孩子表示法
把每个结点的孩子排列起来,以单链表做存储结构,则n个结点有n个孩子链表,如果是叶子结点那么此单链表为空,然后n个头指针有组成一个线性表,采用顺序存储结构,存在一个一位数组中,如果还需要寻找孩子的双亲,再结合双亲表示法,就行了。就是说顺序存储中嵌套了链表。
定义代码:
使用了三个结构体来定义
typedef struct CTNode//定义孩子结点
{
int child;
struct CTNode *next;
}*ChildPtr;
typedef struct//表头结构
{
TElemType data;
ChildPtr firstchild;
int parent;
}CTBox;
typedef struct
{
CTBox nodes[M];
int r,n;
}Ctree;// 根位置数和结点数
4.孩子兄弟表示法
任意一棵树,他结点的第一个孩子若存在就是唯一的,结点的右兄弟若存在也是唯一的,因此设置两个指针,指向该结点的第一个孩子和此结点的右兄弟,若要找双亲再加一个parent指针就行。也把一颗复杂的树变成了一颗二叉树。
定义代码:
这种方式只用一种结构体,是不是方便了许多
typedef struct CSNode//定义树
{
TelemType data;
struct CSNode *firstchild,*rightsib;
}CSNode,*CSNodePtr;
我们在看上面树的表示方法,最大好处是把一颗复杂的树变成了一颗二叉树:
后记
树的存储方法这里有三种,但是最后一种把一颗复杂的树变成了一颗二叉树,于是我们只需要讨论二叉树的各种操作就行了
以上就是树的各种储存结构,喜欢的多多支持哦~