本次主要介绍树的三种基础存储结构:双亲表示法,孩子表示法(孩子双亲表示法),孩子兄弟表示法(孩子兄弟双亲表示法)
树的结构图
- 双亲表示法 : 由图可以看出B、C的双亲是A,D的双亲也就是B以此类推,我们便可以设计出一种存储结构,用一个双亲指针来指向双亲节点,比如B、C的结构里就可以存储A的指针位置,和他们的数据,这样我们很快就能找到某个节点的双亲了,但这样想查找孩子节点就会很麻烦。
- 孩子表示法(孩子双亲表示法) : 由图可以看出A的孩子有B、C,D的孩子有G、H、I,所以我们完全可以定义一个存储结构,将归属于同一个结点的孩子用链表关联起来,双亲节点定义一个指针指向第一个字节点,比如A指向B,B指向C。(孩子双亲节点就是加了一个双亲指针,过于简单,所以这里不做讨论,代码里已经体现)。
- 孩子兄弟表示法(孩子兄弟双亲表示法) : 由图可以看出B和C是兄弟,C是B的右兄弟,而C没有右兄弟,以左为基准,E是C的第一个孩子,F是E的右兄弟,所以我们可以定义一个存储结构,每个节点都有一个右兄弟指针和指向第一个子节点的指针。(孩子兄弟双亲表示法同理也是加一个双亲指针,这里也不进行讨论)。
- 对于这三种存储结构已经总结完毕,下面是代码的演示,具体实现思路代码里已经进行注释,如有不懂的地方可以参考顺序存储结构和链表存储结构。
#include <stdio.h>
#define MAXSIZE 100
typedef int ElemType;
/*双亲表示法*/
//定义子结点存储结构
typedef struct
{
ElemType data; //数据域
int parents; //指向双亲节点的下标 根节点为-1
}PNode;
//双亲表示法的树存储结构
typedef struct
{
PNode nodes[MAXSIZE]; //结点的存储数组
int rootIndex, nodeSum; //rootIndex 根节点的位置, nodeSum 结点总数
}PTree;
/*我是分割线-------------------------------------------------------------------------------------------------------------*/
/*孩子表示法 && 孩子双亲表示法*/
//定义孩子指针的存储结构
typedef struct CNode
{
int child; //数据域,存储指向此结点的下标
struct CNode *next; //指向下一个孩子结点,不存在为空
}*CNodePtr;
//孩子表示法定义头结点存储结构
typedef struct
{
ElemType data; //数据域
CNodePtr node; //存储第一个孩子的指针
}ChildNode;
//孩子双亲表示法定义头结点存储结构
typedef struct
{
ElemType data; //数据域
int parents; //双亲的下标,根节点为-1
CNodePtr node; //存储第一个孩子的指针
}CPNode;
//定义孩子表示法的树的存储结构
typedef struct
{
ChildNode nodes[MAXSIZE]; //结点的存储数组,这里只需要把ChildNode换成CPNode就是孩子双亲的节点存储数组了
int rootIndex, nodeSum; //rootIndex 根节点的位置, nodeSum 结点总数
}CTree;
/*我是分割线-------------------------------------------------------------------------------------------------*/
/*孩子兄弟表示法 && 孩子双亲兄弟表示法*/
//孩子兄弟存储结构
typedef struct CBNode
{
ElemType data; //数据域
struct CBNode *firstChild, *brother; //firstChild 第一个孩子节点; brother 右兄弟节点; 如果不存在则为空
}CBNode, *CBTree; //加这个CBNode是为了开辟内存空间方便
//孩子双亲兄弟存储结构
typedef struct CBPNode
{
ElemType data; //数据域
struct CBPNode *firstChild, *brother, *parents; //firstChild 第一个孩子节点; brother 右兄弟节点; parents 双亲节点; 如果不存在则为空
}CBPNode, *CBPTree; //加这个CBPNode是为了开辟内存空间方便
int main(void)
{
printf("%s\n", "hello");
return 0;
}