关于树的存储结构的结点的表示方式

这里简单的主要介绍下三种对树的存储结构的表示

双亲表示法

如果我们以一组连续的存储空间存储树的结点,在每个结点当中我们去附加一个指示器指示其双亲结点的位置,其的结点结构如下所示
这里写图片描述

其中data是数据域,存储的是结点的数据信息,parent是指针域,存储的是该结点的双亲在数组当中的下标

以双亲表示法的结点结构的定义代码定义如下所示,根结点没有双亲,其的双亲域就设置为-1

#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;

在双亲表示法当中,我们可以根据parent指针就可以很容易的去找到其的双亲结点,时间复杂度为O(1)

如果我们想要知道某一结点的孩子结点,我们相应的可以给其去设置相应的双亲域、长子域、还有右兄弟域等

其实存储结构的设计是一个非常灵活的过程,一个存储结构设计得是否是合理的,取决于基于该存储结构的运算是否适合、是否方便,时间复杂度等等

孩子表示法

如果树当中的每个结点可能有多棵子树,我们可以考虑使用多重链表,即每个结点都有多个指针域,其中每个指针指向一棵子树的根节点,这种方法就是多重链表表示方法

把每个结点的孩子结点给排列起来,然后以单链表作为存储结构,n个结点有n个孩子链表,如果是叶子结点则此单链表为空,然后n个头指针又组成一个线性表,采用顺序存储结构,存放一个一维数组里面,就比如说对于下面的这个树,其的表示形式如下所示

这里写图片描述
这里写图片描述

为了实现上面说的存储结构,我们可以设置两种结点的结构

孩子结点的结构
这里写图片描述

其中的child是数据域,用来存储某个结点在表头数组当中的下标,next是指针域,用来存储指向某个结点的下一个孩子结点的指针

关于表头结点的结构定义
这里写图片描述

这里面data是数据域,存储某结点的数据信息,firstchild是头指针域,存储改结点的孩子链表的头指针

对于孩子表示法的结构定义代码如下所示

/* 树的孩子表示法结构定义 */
#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;

对于这样的结构来说,如果我们要去查找某个结点的某个孩子,或者去查找某个结点的兄弟我们只需要去查找这个结点的孩子单链表就可以了

如果我们想要知道某个结点的双亲是谁,我们可以再为我们之前定义的存储结构加一个parent字段,这种表示方式就是双亲孩子表示法

这里写图片描述

孩子兄弟表示法

对于任意一棵树,它的结点的第一个孩子如果存在就是唯一的,它的右兄弟如果存在也是唯一的。因此,我们设置两个指针,分别指向该结点的第一个孩子和此结点的右兄弟

其结点的结构定义如下所示
这里写图片描述

其中data是数据域,firstchild为指针域,存储该结点的第一个孩子结点的存储地址,rightsib是指针域,存储该结点的右兄弟结点的存储地址

关于树的结构定义代码如下所示

/* 树的孩子兄弟表示法结构定义 */
typedef struct CSNode
{
    TElemType data;
    struct CSNode *firstchild, 
                  *rightsib;
} CSNode, *CSTree;

有了这种表示方法,给查找某个结点的某个孩子带来了方便,只需要通过fistchild找到此结点的长子,然后再通过长子结点的rightsib找到它的二弟,接着一直下去,直到找到具体的孩子,如果我们想要去找双亲,其实更改其的存储结构,加一个双亲的字段就可以了

猜你喜欢

转载自blog.csdn.net/zcmuczx/article/details/80964609