用“孩子链表表示法”表示二叉树并实现其操作:#define MAX_TREENODE_NUM 100 // "孩子链表表示法" 中二叉树的最大节点个数 // "孩子链表表示法" 中孩子链表节点结构体类型定义 typedef struct ChildNode { int Child; // 孩子节点的位置(索引号) struct ChildNode *Next; // 指向下一个孩子的指针 }ChildNode; // "孩子链表表示法" 中二叉树节点结构体类型定义 typedef struct DataNode { char Data; // 二叉树中节点的数据类型 struct ChildNode *FirstChild; // 指向二叉树中节点的第一个孩子的指针 }DataNode; // "孩子链表表示法" 中二叉树结构体类型定义 typedef struct ChildTree { DataNode Nodes[ MAX_TREENODE_NUM ]; // 二叉树的"孩子链表表示法" int Root; // 树根节点的游标 - 静态指针值 int TreeNodeNum // 二叉树中实际的节点数目 }ChildTree; 要求完成如下设计并编写代码、调试通过给出完整的c语言代码包含主函数: (1)设计函数将二叉树以“孩子链表表示法”输入到计算机中(自定义输入数据的格式和方式) (2)设计函数计算“孩子链表表示法”下二叉树的叶子结点个数。(3)设计函数实现如下功能:给定结点数据,判断其是否为叶子结点。如果是则输出叶子结点到根结点的路径。
时间: 2023-12-14 16:36:34 浏览: 87
下面是完整的代码实现:
```c
#include <stdio.h>
#include <stdlib.h>
#define MAX_TREENODE_NUM 100
// "孩子链表表示法" 中孩子链表节点结构体类型定义
typedef struct ChildNode {
int Child; // 孩子节点的位置(索引号)
struct ChildNode *Next; // 指向下一个孩子的指针
} ChildNode;
// "孩子链表表示法" 中二叉树节点结构体类型定义
typedef struct DataNode {
char Data; // 二叉树中节点的数据类型
struct ChildNode *FirstChild; // 指向二叉树中节点的第一个孩子的指针
} DataNode;
// "孩子链表表示法" 中二叉树结构体类型定义
typedef struct ChildTree {
DataNode Nodes[MAX_TREENODE_NUM]; // 二叉树的"孩子链表表示法"
int Root; // 树根节点的游标 - 静态指针值
int TreeNodeNum; // 二叉树中实际的节点数目
} ChildTree;
// 函数声明
void CreateTree(ChildTree *T); // 创建二叉树
int CountLeafNodes(ChildTree T); // 计算叶子节点个数
int IsLeafNode(ChildTree T, int index); // 判断是否为叶子节点
void PrintPath(ChildTree T, int index); // 输出叶子节点到根节点的路径
int main() {
ChildTree T;
CreateTree(&T);
printf("叶子节点个数为:%d\n", CountLeafNodes(T));
char data;
printf("请输入要查询的节点数据:");
scanf("%c", &data);
getchar(); // 消耗掉输入时的回车符
int index = -1;
for (int i = 0; i < T.TreeNodeNum; i++) {
if (T.Nodes[i].Data == data) {
index = i;
break;
}
}
if (index == -1) {
printf("未找到该节点!\n");
} else if (IsLeafNode(T, index)) {
printf("该节点是叶子节点,路径为:");
PrintPath(T, index);
printf("\n");
} else {
printf("该节点不是叶子节点!\n");
}
return 0;
}
// 创建二叉树
void CreateTree(ChildTree *T) {
printf("请输入节点数目:");
scanf("%d", &T->TreeNodeNum);
getchar(); // 消耗掉输入时的回车符
printf("请输入根节点数据:");
scanf("%c", &T->Nodes[0].Data);
getchar(); // 消耗掉输入时的回车符
T->Nodes[0].FirstChild = NULL;
T->Root = 0;
printf("请按照层序遍历顺序依次输入各节点数据(采用字符输入,#表示空节点):\n");
for (int i = 1; i < T->TreeNodeNum; i++) {
scanf("%c", &T->Nodes[i].Data);
getchar(); // 消耗掉输入时的回车符
T->Nodes[i].FirstChild = NULL;
int parent;
printf("请输入第%d个节点的双亲节点位置(输入-1表示该节点为根节点):", i);
scanf("%d", &parent);
if (parent == -1) { // 根节点没有双亲节点
T->Nodes[T->Root].FirstChild = (ChildNode *) malloc(sizeof(ChildNode));
T->Nodes[T->Root].FirstChild->Child = i;
T->Nodes[T->Root].FirstChild->Next = NULL;
} else { // 将当前节点加入到双亲节点的孩子链表中
ChildNode *p = T->Nodes[parent].FirstChild;
if (p == NULL) { // 双亲节点的孩子链表为空
T->Nodes[parent].FirstChild = (ChildNode *) malloc(sizeof(ChildNode));
T->Nodes[parent].FirstChild->Child = i;
T->Nodes[parent].FirstChild->Next = NULL;
} else {
while (p->Next != NULL) { // 找到孩子链表的末尾
p = p->Next;
}
p->Next = (ChildNode *) malloc(sizeof(ChildNode));
p->Next->Child = i;
p->Next->Next = NULL;
}
}
}
}
// 计算叶子节点个数
int CountLeafNodes(ChildTree T) {
int count = 0;
for (int i = 0; i < T.TreeNodeNum; i++) {
if (T.Nodes[i].FirstChild == NULL) { // 没有孩子节点,即为叶子节点
count++;
}
}
return count;
}
// 判断是否为叶子节点
int IsLeafNode(ChildTree T, int index) {
return T.Nodes[index].FirstChild == NULL;
}
// 输出叶子节点到根节点的路径
void PrintPath(ChildTree T, int index) {
if (index == T.Root) { // 已经到达根节点
printf("%c", T.Nodes[index].Data);
return;
}
PrintPath(T, T.Nodes[index].FirstChild->Child); // 递归输出父节点
printf("->%c", T.Nodes[index].Data);
}
```
阅读全文