[题解]二叉树的表达

48 篇文章 4 订阅

题目

题目描述

给定有根二叉树 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 n1

输入格式

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 i2,右子结点的下标为 i ∗ 2 + 1 i * 2 + 1 i2+1,从而完成了对一棵树的存储。(由于本题给出的根结点下标不确定,所以这种方法无法直接使用)

多个函数计算不同的量

我定义了多个函数,如果单从代码的行数上来看,可能会觉得并不够简洁。单恰恰是这种方式,在需要计算多个数值时,能够分工明确,更加高效地编写。

当代码中的步骤步骤或计算的量比较多时,应当考虑使用此方式或面向对象编程降低代码编写和调试的难度。


原创不易,感谢支持!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wingaso

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值