“这是我参与8月更文挑战的第31天,活动详情查看:8月更文挑战”
关注我,以下内容持续更新
1. 双亲表示法
1. 普通的树结构
图的存储的结构有双亲表示法、孩子(链表)表示法、双亲孩子表示法、孩子兄弟表示法。本篇主要介绍双亲表示法,如上图所示,把这种普通的树结构用双亲表示法来存储。
双亲表示法的基本思想:树的双亲表示法实质是一种静态链表。用一维数组来存储树的各个结点(一般按层序存储),数组中的一个元素对应树中的一个结点,包括结点的数据信息以及该结点的双亲在数组中的下标。
因为根节点没有父节点(父节点又称为双亲节点),因此根节点记录父节点位置的变量通常置为-1。 采用双亲表示法存储图1中的普通树,其存储状态如图2所示:
2. 双亲表示法
每个结点Node由data和parent构成,如图所示
- data:存储树中结点的数据信息
- parent:存储该结点的双亲在数组中的下标
#define tree_size 100 //宏定义树中结点的最大数量
#define TElemType int //宏定义树结构中数据类型
//结点
typedef struct PTNode{
TElemType data; //树中结点的数据类型
int parent; //结点的父结点在数组中的位置下标
}PTNode;
//树
typedef struct {
PTNode nodes[tree_size]; //存放树中所有结点
int r, n; //根的位置下标和结点数
}PTree;
这种结构来查找双亲结点非常容易,直接找到这个结点的parent域就是双亲结点;但是查询某个结点的孩子结点需要遍历所有的结点,有点复杂,所以可以把双亲表示法进行改造。
2. 改造后的双亲表示法
改造后,增加了firstChild域和rightSib域来提高查找孩子结点的性能。改造后的每个结点Node由data、parent、firstChild和rightSib构成,其存储状态如图3所示:
3. 完善后的双亲表示法
- data:存储树中结点的数据信息
- parent:存储该结点的双亲在数组中的下标
- firstChild:存储该结点的第一个孩子结点在数组中的下标
- rightSib:存储该结点的兄弟结点在数组中的下标
如图,查找B的孩子结点的过程如下:
- 1.查找B结点的firstChild域,值为3。也就是B的第一个孩子结点在数组中的下标为3,也就是D结点;
- 2.查找D结点的rightSib域,值为4。也就是B的第二个孩子结点在数组中的下标为4,也就是E结点;
- 3.查找E结点的rightSib域,值为5。也就是B的第三个孩子结点在数组中的下标为5,也就是F结点;
- 4.查找F结点的rightSib域,值为-1。-1代表F结点没有兄弟结点,所以B结点的孩子结点至此查找完毕;
- 5.至此找到了B结点的所有孩子结点:D、E、F。
再例如查找结点I的孩子结点:因为I结点的firstChild域值为-1,所以它没有孩子结点。
查找D的孩子结点的过程如下:
- 1.查找D结点的rightSib域,值为4。也就是D的第一个兄弟结点在数组中的下标为4,也就是E结点;
- 2.查找E结点的rightSib域,值为5。也就是D的第二个兄弟结点在数组中的下标为5,也就是F结点;
- 3.查找F结点的rightSib域,值为-1。-1代表F结点没有兄弟结点,所以D结点的兄弟结点至此查找完毕;
- 4.一共找到了D的所有兄弟结点:E、F。
关注我
如果觉得我写的不错,请点个赞 关注我, 您的支持是我更文最大的动力!