问题链接
问题内容
对于给定的二叉树,输出各结点u的信息,信心包括u的结点编号,u的深度,u的父结点,u的高,u的兄弟结点,结点的种类(根、内部结点、叶)、u的子结点数。
思路
由于这是二叉树,实际上简化了有根树的数据结构的实现
(1)结点编码由题目可知,父结点通过Tree[u].parent可知
(2)深度和高,通过递归遍历求得,其中高是求左右结点的高的最大值
(3)u的兄弟结点、子结点数分别判断父结点的子结点情况和自身的子结点情况
(4)结点的种类用上一节的性质可知
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
const int MAX = 100005;
const int NIL = -1;
struct Node {
int parent, left, right;
};
Node Tree[MAX];
int n, Depth[MAX], Height[MAX];
int getDegree(int u) {
int deg = 0;
if (Tree[u].left != NIL)
deg++;
if (Tree[u].right != NIL)
deg++;
return deg;
}
void setDepth(int u, int depth) {
if (u == NIL)
return;
Depth[u] = depth;
setDepth(Tree[u].left, depth + 1);
setDepth(Tree[u].right, depth + 1);
}
int setHeight(int u) {
int h1 = 0, h2 = 0;
if (Tree[u].left != NIL)
h1 = setHeight(Tree[u].left) + 1;
if (Tree[u].right != NIL)
h2 = setHeight(Tree[u].right) + 1;
return Height[u] = max(h1, h2);
}
int getSibling(int u) {
if (Tree[u].parent == NIL)
return NIL;
//存在左兄弟
if (Tree[Tree[u].parent].left != u && Tree[Tree[u].parent].left != NIL)
return Tree[Tree[u].parent].left;
//存在右兄弟
if (Tree[Tree[u].parent].right != u && Tree[Tree[u].parent].right != NIL)
return Tree[Tree[u].parent].right;
return NIL;
}
void print(int u) {
printf("node %d: parent = %d, sibling = %d, degree = %d, depth = %d, height = %d, "
, u, Tree[u].parent, getSibling(u), getDegree(u), Depth[u], Height[u]);
if (Tree[u].parent == NIL)
printf("root\n");
else if (Tree[u].left != NIL || Tree[u].right != NIL)
printf("internal node\n");
else
printf("leaf\n");
}
int main() {
int n;
int u, l, r, root;
scanf("%d", &n);
for (int i = 0; i < n; i++) {
Tree[i].parent = Tree[i].left = Tree[i].right = NIL;
}
for (int i = 0; i < n; i++) {
scanf("%d %d %d", &u, &l, &r);
Tree[u].left = l;
Tree[u].right = r;
Tree[l].parent = u;
Tree[r].parent = u;
}
for (int i = 0; i < n; i++) {
if (Tree[i].parent == NIL)
root = i;
}
setHeight(root);
setDepth(root, 0);
for (int i = 0; i < n; i++)
print(i);
return 0;
}