双亲表示法
实现:定义结构数组存放树的结点,每个结点包含两个域:
- 数据域:存放结点本身信息
- 双亲域:指示本结点的双亲结点在数组中的位置
结点结构:
结点类型定义:
typedef struct PTNode
{//结点类型定义
TElemType data;
int parent; //双亲位置域
}PTNode;
另外,用 r
存储根结点的下标,用 n
表示结点个数
树的双亲表示法示例:
树结构类型定义:
#define MAX_TREE_SIZE 100
typedef struct
{//树结构类型定义
PTNode nodes[MAX_TREE_SIZE];
int r,n; //根结点的位置和结点个数
}PTree;
特点:找双亲容易,找孩子难
孩子表示法
实现:把每个结点的孩子结点排列起来,看成是一个线性表,用单链表作存储,则 n 个结点有 n 个孩子链表(叶子的孩子链表为空表)。而 n 个头指针又组成一个线性表,用顺序表(含 n 个元素的结构数组)存储。
孩子结点结构:
孩子结点类型定义:
typedef struct CTNode
{
int child;
struct CTNode *next;
}*ChildPtr;
双亲结点结构:
双亲结点类型定义:
typedef struct
{
TElemType data;
ChildPtr firstchild; //指向孩子的指针
}CTBox;
树的孩子表示法示例:
树结构类型定义:
typedef struct
{
CTBox nodes[MAX_TREE_SIZE];
int n,r; //结点数和根结点的位置
}CTree;
特点:找孩子容易,找双亲难
这个特点与双亲表示法相反,我们可以把双亲表示法和孩子表示法结合起来,这样,找孩子容易,找双亲也容易
只需要增加一个成员,就是增加双亲结点的下标
孩子兄弟法
实现:用二叉链表作树的存储结构,链表中的每个结点的两个指针域分别指向其第一个孩子结点和下一个兄弟结点
结点结构:
树的二叉链表表示法示例:
树结构类型定义:
typedef struct CSNode
{
ElemType data;
struct CSNode *firstchild,*nextsibling;//孩子指针域和兄弟指针域
}CSNode,*CSTree;
特点:便于实现树的各种操作,如容易找结点孩子
若要访问结点 x 的第 i 个孩子,则只要先从 fistchild 域找到第一个孩子结点,然后沿着孩子结点的 nextsibling 域连续走 i-1 步,便可以找到 x 的第 i 个孩子。当然,如果为每个结点增设一个 parent 域,则同样能方便地实现查找双亲的操作
借鉴:《数据结构》严蔚敏 青岛大学–王卓