求一颗树任意两个节点的距离

本文通过C++代码详细解释如何在树形结构中找到两个给定节点的最近公共祖先。包括代码实现、测试用例及解析过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这个题可以先画树来看看,要知道它们共同的父亲就好了,可是共同父亲怎么知道呢?那我们从它的左子树和右子树找这两个节点。

来看个图比较好理解点吧,

如果当前节点是两个节点的共同父亲,或者是图中那种描述呢

直接来看C++代码吧

typedef struct Node{
	Node* left;
	Node* right;
	int val;
	Node(int v):val(v),left(NULL),right(NULL){}
}Node,*pNode;


int NodeDistance(pNode root,pNode first,pNode second,int &dist)
{
	if(root==NULL)
		return 0;
	int va=0;
	if(root==first||root==second)
		va=1;
	int valeft=NodeDistance(root->left,first,second,dist);
	int varight=NodeDistance(root->right,first,second,dist);
	if(!dist)
	{		
		if(valeft*va||varight*va||varight*valeft)
		{
			dist=varight+valeft;
			return 0;
		}
		else
			if(va||varight||valeft)
				return va?va:varight+valeft+1;
	}
	return 0;
}
最后给个测试用例吧

void  main()
{
	pNode root=new Node(1);
	root->left=new Node(2);
	root->right=new Node(3);
	root->left->left=new Node(6);
	root->left->right=new Node(7);
	root->right->left=new Node(8);
	root->right->right=new Node(9);
	root->left->left->right=new Node(10);
	root->left->left->left=new Node(11);
	root->right->left->left=new Node(12);
	root->right->left->left->right=new Node(13);

	int d=0;
	NodeDistance(root,root->right->left->left->right,root->left->right,d);
	while(1);
}


### 计算二叉中最大带权路径和的算法 为了计算二叉中的最大带权路径和,可以采用递归方法来遍历整棵并记录每条可能路径上的权重总和。以下是详细的解释以及实现: #### 算法描述 定义一个函数 `maxPathSum` 来计算从当前节点到其子内的任意一条路径的最大权重和。对于每一个节点,考虑两种情况: 1. **单边路径**:仅通过左子或右子到达某个叶子节点。 2. **双边路径**:经过当前节点连接左子和右子形成的一条完整路径。 最终的结果是从根节点出发能够找到的最大路径和。需要注意的是,在某些情况下,可能存在负数权重的情况,因此需要特别处理这些场景以确保不会错误地增加路径权重。 下面是具体的 C++ 实现代码: ```cpp #include <iostream> #include <algorithm> // std::max using namespace std; // 定义二叉结构体 struct TreeNode { int weight; TreeNode *left, *right; TreeNode(int val) : weight(val), left(nullptr), right(nullptr) {} }; class Solution { public: int max_sum = INT_MIN; // 初始化全局变量用于保存最大路径和 // 辅助函数:返回以当前节点为起点的最大贡献值(即单边路径) int helper(TreeNode* node) { if (!node) return 0; // 如果为空,则不提供任何贡献 // 对于左右子分别递归调用helper获取它们能提供的最大正向贡献 int left_gain = max(helper(node->left), 0); int right_gain = max(helper(node->right), 0); // 更新最大路径和 (当前节点作为最高点形成的路径) int price_newpath = node->weight + left_gain + right_gain; max_sum = max(max_sum, price_newpath); // 返回当前节点及其最佳一侧构成的路径所能带来的收益 return node->weight + max(left_gain, right_gain); } // 主函数入口 int findMaxPathSum(TreeNode* root) { helper(root); return max_sum; } }; ``` 上述程序实现了寻找二叉中具有最大带权路径的功能,并且考虑到如果某一边的路径权重小于零则忽略它[^3]。 #### 复杂度分析 时间复杂度 O(N),其中 N 是节点的数量,因为每个节点只被访问一次;空间复杂度取决于栈深度,最坏的情况下也是O(H),H代表的高度。 ---
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值