18923 二叉树的直径 SCAU 数据结构 笔记

/*18923 二叉树的直径
时间限制:1000MS  代码长度限制:10KB
提交次数:0 通过次数:0

题型: 编程题   语言: 不限定
Description
给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过也可能不穿过根结点。
		  1
		 / \
		2   3
	   / \
	  4   5
答案为3, 它的长度是路径 [4,2,1,3] 或者 [5,2,1,3]。



输入格式
共n行。
第一行一个整数n,表示有n个结点,编号为1至n。
第二行至第n行,每行有两个整数x和y,表示在二叉树中x为y的父节点。x第一次出现时y为左孩子


输出格式
输出二叉树的直径。


输入样例
5
1 2
1 3
2 4
2 5


输出样例
3

所谓二叉树的直径,就是以某一结点为根,左右子树深度之和减1
*/

#include<stdio.h>
#include<math.h>
int tree[100] = { 0 };  //用来存储树的节点数据
int treeNum[100] = { 0 };//出来存储树的节点是放在哪个序号
int diameter = 0;
void  f(int p, int c)
{
	if (tree[2 * treeNum[p]] == 0)
	{
		tree[2 * treeNum[p]] = c;//放数据
		treeNum[c] = 2 * treeNum[p];//放数据的在树里面的序号
	}//左子树没有被占用放左子树
	else
	{
		tree[2 * treeNum[p] + 1] = c;
		treeNum[c] = 2 * treeNum[p] + 1;
	}//放在右子树
}

int dfs(int root)
{
	if (tree[root] == 0) //访问到空结点,显然直径为0
	{
		return 0;
	}
	int left = dfs(2 * treeNum[tree[root]]); //后续求取左右子树的各自经过的最大结点数,不包括当前root
	int right = dfs(2 * treeNum[tree[root]] + 1);
	//后序操作,更新最长路径的值
	if (diameter < left + right + 1)//因为L和R是 不包括当前结点  的子树的最深路径经过的结点数,因此,结果更新要加上当前root
		diameter = left + right + 1;

	if (left > right)  //同理,返回当前子树最大深度经过的结点数
		return left + 1;
	else
		return right + 1;
}

int main()
{
	int n;
	scanf("%d", &n);
	if (n == 1)
	{
		printf("1");
		return 0;
	}//只有一个节点
	int p, c;
	scanf("%d %d", &p, &c);
	tree[1] = p;
	treeNum[p] = 1;
	tree[2] = c;
	treeNum[c] = 2; //第一次放入 只能手动处理了
	for (int i = 1; i < n - 1; i++)
	{
		scanf("%d %d", &p, &c);
		f(p, c);
	}//录入节点情况
	dfs(1);
	printf("%d", diameter-1);
}

 

  • 7
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值