题目
题目描述
给定有根二叉树 T T T,请编写一个程序,输出其各节点 u u u的如下信息。
- u u u的结点编号
- u u u的深度
- u u u的父结点
- u u u的高
- u u u的兄弟结点
- 结点的种类(根、内部结点、叶)
- u u u出子结点数
设给定二叉树拥有 n n n个结点,编号分别为 0 0 0至 n − 1 n-1 n−1。
输入格式
第 1 1 1行输入结点的个数 n n n。接下来 n n n行按照下述格式输入各结点的信息,每个结点占 1 1 1行。
id left right
i d id id为结点编号, l e f t left left为左子结点编号, r i g h t right right为右子结点编号。不存在子结点时 l e f t ( r i g h t ) left(right) left(right)为-1。
i d id id不一定按顺序给出。
输出格式
按赞下述格式,以结点编号升序输出结点信息。
node id:parent = p,sibling = s,degree = deg,depth = dep,height = h,type
其中 p p p表示父结点的编号,父结点不存在时记作 − 1 -1 −1。 s s s表示兄弟结点的编号,兄弟结点不存在时记作 − 1 -1 −1。
d e g deg deg、 d e p dep dep、 h h h分别表示子结点数、深度、高。 t y p e type type表示结点的类型,从 r o o t root root(根)、 i n t e r n a l n o d e internal\ node internal node(内部结点)、 l e a f leaf leaf(叶)三个字符串中选择其一。
题解
#include<cstdio>
#include<cstring>
#include<string>
using namespace std;
const int N = 1000;
int Parent[N],Son[N][2];
string NodeType[] = {"root","internal node","leaf"};
int getHeight(int idx){
if(Son[idx][0] == -1 && Son[idx][1] == -1) return 0;
int l = 0,r = 0;
if(~Son[idx][0]) l = getHeight(Son[idx][0]) + 1;
if(~Son[idx][1]) r = getHeight(Son[idx][1]) + 1;
return max(l,r);
}
int getDepth(int idx){
int cnt = 0;
while(~Parent[idx]) cnt ++,idx = Parent[idx];
return cnt;
}
int getDegree(int idx){
int s = 0;
if(Son[idx][0] != -1 || Son[idx][1] != -1) s = 1;
if(Son[idx][0] != -1 && Son[idx][1] != -1) s = 2;
return s;
}
int getSibling(int idx){
int s = -1;
if(~Parent[idx]) s = Son[Parent[idx]][0];
if(s == idx) s = Son[Parent[idx]][1];
return s;
}
string getNodeType(int idx){
int ty = 1;
if(Son[idx][0] == -1 && Son[idx][1] == -1) ty = 2;
if(Parent[idx] == -1) ty = 0;
return NodeType[ty];
}
int main(){
int n;
scanf("%d",&n);
memset(Parent,-1,sizeof Parent);
for(int i = 0;i < n;i++){
int id,l,r;
scanf("%d%d%d",&id,&l,&r);
Son[id][0] = l;
Son[id][1] = r;
Parent[l] = Parent[r] = id;
}
int root = -1;
for(int i = 0;i < n;i++) if(Parent[i] == -1) root = i;
for(int i = 0;i < n;i++){
// node 0: parent = -1,sibling = -1,degree = 2,depth = 0,height = 3,root
printf("node %d: parent = %d,sibling = %d,degree = %d,depth = %d,height = %d,%s\n",i,Parent[i],getSibling(i),getDegree(i),getDepth(i),getHeight(i),getNodeType(i).c_str());
}
return 0;
}
二叉树的表示法
二叉树是一种特殊的树,因此树的表示法在二叉树中仍然适用。这里我同样使用了双亲表示法+孩子表示法。
二叉树除了可以使用树的表示法之外,还因其特殊性,而有着一些更加常见的表示法,如数组表示法(该表示法适用于本题使用),如下所示:
struct Node{
int val;
int left,right;
};
Node A[N];
在一些情况下,我们能够提前知道该树的根结点,这是可以考虑使用一种更加简便的表示方法:
int Node[N];
我们可以将下标为1的点定为根结点,并且对于任意的点 i i i,让它的左子结点的下标为 i ∗ 2 i * 2 i∗2,右子结点的下标为 i ∗ 2 + 1 i * 2 + 1 i∗2+1,从而完成了对一棵树的存储。(由于本题给出的根结点下标不确定,所以这种方法无法直接使用)
多个函数计算不同的量
我定义了多个函数,如果单从代码的行数上来看,可能会觉得并不够简洁。单恰恰是这种方式,在需要计算多个数值时,能够分工明确,更加高效地编写。
当代码中的步骤步骤或计算的量比较多时,应当考虑使用此方式或面向对象编程降低代码编写和调试的难度。
原创不易,感谢支持!