二叉树:找出2个节点的最近公共祖先

给定二叉树(不是二叉搜索树)和两个节点n1n2,编写程序以找到他们的最近公共祖先(Lowest Common Ancestor, LCA )。

LCA定义

最近公共祖先是两个节点所有公共祖先中离根节点最远的节点。

计算节点的最近公共祖先是很有用的。

例如,为了确定树中节点之间距离:从n1节点到n2节点的距离,可以计算从根到n1的距离加上从根到n2的距离,减去从根到它们最近共同祖先的距离的两倍。

 

方法

我们可以从根开始遍历树。 如果任一给节点(n1和n2)与根匹配,则根为LCA。

如果根与任何节点都不匹配,我们重复左右子树中寻找节点n1和n2。

如果在其左子树中存在一个节点而在右子树中存在的另一个节点,则此节点即为LCA。

如果两个节点都位于左子树中,则LCA也位于左子树中,

否则LCA位于右子树中。

#include <iostream> 
  
using namespace std; 
  
// 二叉树节点
struct Node 
{ 
    struct Node *left, *right; 
    int key; 
}; 
  
// 根据给定的值,创建一个二叉树节点,其左右子树均为空
Node* newNode(int key) 
{ 
    Node *temp = new Node; 
    temp->key = key; 
    temp->left = temp->right = NULL; 
    return temp; 
} 

// 返回指向给定节点 n1 和 n1 LCA 的指针
// 此方法假定节点 n1 和 n2 在数中均出现
struct Node *findLCA(struct Node* root, int n1, int n2) 
{ 
    if (root == NULL) return NULL; 
  
    // 如果任一给节点(n1和n2)与根匹配,则根为LCA
    if (root->key == n1 || root->key == n2) 
        return root; 
  
    // 在左右子树中找给定节点
    Node *left_lca  = findLCA(root->left, n1, n2); 
    Node *right_lca = findLCA(root->right, n1, n2); 
  
    // 左子树存在一个给定节点
// 右子树存在另一给定节点
// 则根为 LCA if (left_lca && right_lca) return root; // 否则 LCA 位于左子树或者右子树 return (left_lca != NULL)? left_lca: right_lca; } int main() { Node * root = newNode(1); root->left = newNode(2); root->right = newNode(3); root->left->left = newNode(4); root->left->right = newNode(5); root->right->left = newNode(6); root->right->right = newNode(7); cout << "LCA(4, 5) = " << findLCA(root, 4, 5)->key; cout << "nLCA(4, 6) = " << findLCA(root, 4, 6)->key; cout << "nLCA(3, 4) = " << findLCA(root, 3, 4)->key; cout << "nLCA(2, 4) = " << findLCA(root, 2, 4)->key; return 0; }

 

 








 

转载于:https://www.cnblogs.com/xielei/p/10604018.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一段Java代码,用于找出二叉树两个节点之间的距离: ``` public class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; } } public class BinaryTreeDistance { public int findDistance(TreeNode root, int node1, int node2) { TreeNode lca = findLCA(root, node1, node2); int dist1 = findDistanceFromNode(lca, node1); int dist2 = findDistanceFromNode(lca, node2); return dist1 + dist2; } private TreeNode findLCA(TreeNode root, int node1, int node2) { if (root == null || root.val == node1 || root.val == node2) { return root; } TreeNode left = findLCA(root.left, node1, node2); TreeNode right = findLCA(root.right, node1, node2); if (left != null && right != null) { return root; } return left != null ? left : right; } private int findDistanceFromNode(TreeNode node, int target) { if (node == null) { return -1; } if (node.val == target) { return 0; } int left = findDistanceFromNode(node.left, target); int right = findDistanceFromNode(node.right, target); if (left == -1 && right == -1) { return -1; } else { return 1 + Math.max(left, right); } } } ``` 在上面的代码中,findDistance 方法接收三个参数:根节点、目标节点 1 的值、目标节点 2 的值。该方法首先找出最近公共祖先节点(LCA),然后使用 LCA 到目标节点的距离计算目标节点之间的距离。findLCA 方法通过递归遍历二叉树来查找 LCA,而 findDistanceFromNode 方法计算给定节点到目标节点的距离。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值