问题描述
给定有根二叉树T,请编写一个程序,输出其各结点u的如下信息:
u的结点编号
u的深度
u的父结点
u的高
u的兄弟结点
结点的种类(根、内部结点、叶)
u的子结点数
设给定二叉树拥有n个结点,编号分别为0至n-1。
输入: 第1行输入结点的个数n。接下来n行按照下述格式输入各结点的信息,每个结点占1行。
id left right
id为结点编号,left为左子结点编号,right为右子结点编号。不存在子结点时left(right)为-1。
输出: 按照下述格式输出结点信息。
node id: parent = p, sibling = s, degree = deg, depth = dep, height = h, type
其中p表示父结点的编号,父结点不存在时记作-1。s表示兄弟结点的编号,兄弟结点不存在时记作-1。
deg、dep、h分别表示子结点数、深度、高。type表示结点的类型,从root(根)、internal node(内部结点)、leaf(叶)三个字符串中选择其一。
限制: 1 ≤ n ≤ 25
输入示例
9
0 1 4
1 2 3
2 -1 -1
3 -1 -1
4 5 8
5 6 7
6 -1 -1
7 -1 -1
8 -1 -1
输出示例
node 0: parent = -1, sibling = -1, degree = 2, depth = 0, height = 3, root
node 1: parent = 0, sibling = 4, degree = 2, depth = 1, height = 1, internal node
node 2: parent = 1, sibling = 3, degree = 0, depth = 2, height = 0, leaf
node 3: parent = 1, sibling = 2, degree = 0, depth = 2, height = 0, leaf
node 4: parent = 0, sibling = 1, degree = 2, depth = 1, height = 2, internal node
node 5: parent = 4, sibling = 8, degree = 2, depth = 2, height = 1, internal node
node 6: parent = 5, sibling = 7, degree = 0, depth = 3, height = 0, leaf
node 7: parent = 5, sibling = 6, degree = 0, depth = 3, height = 0, leaf
node 8: parent = 4, sibling = 5, degree = 0, depth = 2, height = 0, leaf
讲解
二叉树结点的数量固定,可以利用结构体数组实现
struct Node{
int parent, left, right;
};
结点没有左/右结点时,我们将left/right设为NIL。NIL在这里起到标记的作用,它的值不在结点编号范围内,比如-1。
下述递归算法可以求出结点u的高
setHeight(H, u)
h1 = h2 = 0
if T[u].right != NIL
h1 = setHeight(H, T[u].right) + 1
if T[u].left != NIL
h2 = setHeight(H, T[u].left) + 1
return H[u] = max(h1, h2)
AC代码如下
#include<cstdio>
#define MAX 10000
#define NIL -1
struct Node { int parent, left, right; };
Node T[MAX];
int n, D[MAX], H[MAX];
void setDepth(int u, int d){
if(u == NIL) return;
D[u] = d;
setDepth(T[u].left, d + 1);
setDepth(T[u].right, d + 1);
}
int setHeight(int u){
int h1 = 0, h2 = 0;
if(T[u].left != NIL)
h1 = setHeight(T[u].left) + 1;
if(T[u].right != NIL)
h2 = setHeight(T[u].right) + 1;
return H[u] = (h1 > h2 ? h1 : h2);
}
//返回结点u的兄弟结点
int getSibling(int u){
if(T[u].parent == NIL) return NIL;
if(T[T[u].parent].left != u && T[T[u].parent].left != NIL)
return T[T[u].parent].left;
if(T[T[u].parent].right != u && T[T[u].parent].right != NIL)
return T[T[u].parent].right;
return NIL;
}
void print(int u){
printf("node %d: ", u);
printf("parent = %d, ", T[u].parent);
printf("sibling = %d, ", getSibling(u));
int deg = 0;
if(T[u].left != NIL) deg++;
if(T[u].right != NIL) deg++;
printf("degree = %d, ", deg);
printf("depth = %d, ", D[u]);
printf("height = %d, ", H[u]);
if(T[u].parent == NIL){
printf("root\n");
} else if (T[u].left == NIL && T[u].right == NIL){
printf("leaf\n");
} else {
printf("internal node\n");
}
}
int main(){
int v, l, r, root = 0;
scanf("%d", &n);
for(int i = 0; i < n; i++) T[i].parent = NIL;
for(int i = 0; i < n; i++){
scanf("%d %d %d", &v, &l, &r);
T[v].left = l;
T[v].right = r;
if(l != NIL) T[l].parent = v;
if(r != NIL) T[r].parent = v;
}
for(int i = 0; i < n; i++) if(T[i].parent == NIL) root = i;
setDepth(root, 0);
setHeight(root);
for(int i = 0; i < n; i++) print(i);
return 0;
}