有根树【东北大学oj数据结构7-1】C语言
创建一个程序,为给定的有根树 T 的每个节点 u 输出以下信息。
u的节点号
u的父节点号
u的深度
u的节点类型(根、内部节点或叶)
u的孩子名单
这里我们假设给定的树有n个节点,每个节点都分配了一个从0到n-1的数字。
输入
输入的第一行给出节点数 n。在接下来的第 n 行,每个节点的信息按以下格式在一行中给出。
idkc1c2...ck
id 是节点号,k 是顺序。 c1c2...ck 表示第一个子节点的节点号,... 表示第k 个子节点的节点号。
输出
按照以下格式输出节点信息。按编号升序输出节点信息。
node id: parent = p, depth = d, type, [c1...ck]
p 表示父编号。但是,如果您没有父级,请将其设置为 -1。 d 表示节点的深度。
type 是分别代表根、内部节点和叶的根、内部节点或叶字符串之一。但是,如果根满足叶子和内部节点的条件,则应该是根。
c1c2...ck 是一个孩子的列表。请将其视为一个序列树,并按照输入的顺序输出。请注意逗号空格分隔符。检查输出示例中的输出格式。
数据约束
1 ≤ n ≤ 100,000
节点深度不超过20。
任何两个节点之间总是有一条路径。
输入样例
13
0 3 1 4 10
1 2 2 3
2 0
3 0
4 3 5 6 7
5 0
6 0
7 2 8 9
8 0
9 0
10 2 11 12
11 0
12 0
输出样例
node 0: parent = -1, depth = 0, root, [1, 4, 10]
node 1: parent = 0, depth = 1, internal node, [2, 3]
node 2: parent = 1, depth = 2, leaf, []
node 3: parent = 1, depth = 2, leaf, []
node 4: parent = 0, depth = 1, internal node, [5, 6, 7]
node 5: parent = 4, depth = 2, leaf, []
node 6: parent = 4, depth = 2, leaf, []
node 7: parent = 4, depth = 2, internal node, [8, 9]
node 8: parent = 7, depth = 3, leaf, []
node 9: parent = 7, depth = 3, leaf, []
node 10: parent = 0, depth = 1, internal node, [11, 12]
node 11: parent = 10, depth = 2, leaf, []
node 12: parent = 10, depth = 2, leaf, []
#include <stdio.h>
#define MAX 100005
#define NIL -1
// 定义树的节点结构
struct Node {
int p, l, r; // p 是父节点, l 是子节点, r 是右侧兄弟节点
};
struct Node T[MAX]; // 树节点数组
int D[MAX]; // 存储每个节点的深度
int n; // 节点的数量
// 打印一个节点的信息
void print(int u) {
int i, c;
printf("node %d: ", u);
printf("parent = %d, ", T[u].p);
printf("depth = %d, ", D[u]);
if (T[u].p == NIL) {
printf("root, ");
} else if (T[u].l == NIL) {
printf("leaf, ");
} else {
printf("internal node, ");
}
printf("[");
for (i = 0, c = T[u].l; c != NIL; i++, c = T[c].r) {
if (i) {
printf(", ");
}
printf("%d", c);
}
printf("]\n");
}
// 递归计算每个节点的深度
void rec(int u, int p) {
D[u] = p;
if (T[u].r != NIL) {
rec(T[u].r, p); // 先递归右子树
}
if (T[u].l != NIL) {
rec(T[u].l, p + 1); // 再递归左子树
}
}
int main() {
int i, j, d, v, c, l, r;
// 读入节点数量
scanf("%d", &n);
// 初始化所有节点的父节点、左子节点、右子节点为 NIL
for (i = 0; i < n; i++) {
T[i].p = T[i].l = T[i].r = NIL;
}
// 构建树
for (i = 0; i < n; i++) {
scanf("%d %d", &v, &d); // 输入当前节点编号和子节点数量
l = NIL; // 初始化左子节点的指针
for (j = 0; j < d; j++) {
scanf("%d", &c); // 输入当前节点的子节点
if (j == 0) {
T[v].l = c; // 第一个子节点是左子节点
} else {
T[l].r = c; // 后续子节点是右子节点
}
l = c; // 更新左子节点
T[c].p = v; // 设置当前子节点的父节点
}
}
// 找到根节点(父节点是 NIL)
for (i = 0; i < n; i++) {
if (T[i].p == NIL) {
r = i; // 根节点
break;
}
}
// 计算每个节点的深度
rec(r, 0);
// 输出每个节点的信息
for (i = 0; i < n; i++) {
print(i);
}
return 0;
}
原文地址:https://blog.csdn.net/2401_84017541/article/details/144404917
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!