数据结构总目录
树的孩子表示法
1. 结构解析
在一棵树的结构中,与二叉树相比,最直接的区别就是:对于树的每一个结点, 它的孩子结点数量可以是任意的。
已知需要构建如下树结构
所以为了表示树的孩子结点,树的孩子表示法包括了顺序表和链表两种结构,也可以说是顺序表和链表的结合体
其中顺序表用于存储每个结点的数据,同时链接着一条链表,而该链表则用于记录每个孩子结点的下标位置。
2. 源代码
#include <stdio.h>
#include <stdlib.h>
#define MaxSize 20
typedef char DataType;
// 孩子链表结点
typedef struct CNode
{
int pos; // 孩子位置
struct CNode *next; // 指向兄弟结点
}CNode, *ChildLink;
// 根结点
typedef struct
{
DataType data; // 根结点的数据域
ChildLink child; // 根结点的孩子链表
}TreeRoot;
// 树的整体顺序结构
typedef struct
{
TreeRoot *root;
int length;
}SqCTree;
// 初始化顺序结构
void InitCTree(SqCTree *CT)
{
CT->root = (TreeRoot *)malloc(MaxSize*sizeof(TreeRoot));
CT->length = 0;
// 初始化链表
int i;
for (i = 0; i < MaxSize; i++)
{
// 创建头结点
CT->root[i].child = (CNode *)malloc(sizeof(CNode));
CT->root[i].child->next = NULL;
}
printf("已初始化树\n");
}
// 构建树
void CreateCTree(SqCTree *CT)
{
printf("请输入结点数:");
scanf("%d", &CT->length);
int i, j, num;
for (i = 0; i < CT->length; i++)
{
fflush(stdin);
printf("请输入第%d个结点数据、孩子个数、孩子下标:", i);
scanf("%c %d", &CT->root[i].data, &num);
// 孩子链表
CNode *child = CT->root[i].child;
for (j = 0; j < num; j++)
{
CNode *s = (CNode *)malloc(sizeof(CNode));
scanf("%d", &s->pos);
s->next = NULL;
// 链表尾插法
child->next = s;
child = child->next;
}
}
}
// 先序遍历树
void PreOrderTraverse(SqCTree CT, int pos)
{
if (CT.root)
{
// 输出根结点
printf("%c ", CT.root[pos].data);
// 依次递归孩子结点
CNode *p = CT.root[pos].child;
// 从左到右依次遍历孩子结点
while (p->next)
{
p = p->next;
PreOrderTraverse(CT, p->pos);
}
}
}
// 先序遍历树
void PostOrderTraverse(SqCTree CT, int pos)
{
if (CT.root)
{
// 依次递归孩子结点
CNode *p = CT.root[pos].child;
// 从左到右依次遍历孩子结点
while (p->next)
{
p = p->next;
PostOrderTraverse(CT, p->pos);
}
// 输出根结点
printf("%c ", CT.root[pos].data);
}
}
int main()
{
SqCTree CT;
InitCTree(&CT);
CreateCTree(&CT);
printf("先序遍历:");
PreOrderTraverse(CT, 0);
printf("\n");
printf("后序遍历:");
PostOrderTraverse(CT, 0);
printf("\n");
system("pause");
return 0;
}