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

一、问题描述

给定二叉树(不是二叉搜索树)和两个节点 p 和 q,编程实现找到二者的最近公共祖先(Lowest Common Ancestor,LCA)。

二、思路分析

LCA(Least Common Ancestor):【最近公共祖先】两个节点所有公共祖先中离根节点最远的节点。从根开始遍历树,如果任意给定节点(p和q)与根匹配,则根为 LCA。如果根与任何节点都不匹配,重复左右子树中寻找节点 p 和 q。如果在其左子树中存在一个节点而在右子树中存在的另一个节点,则此节点即为 LCA。如果两个节点都位于左子树中,则 LCA 也位于左子树中,否则 LCA 位于右子树中。由此,找到该树中两个指定节点的最近公共祖先,有三种情况,如图:

树中从 p 节点到 q 节点的距离:从根到 p 的距离加上从根到 q 的距离,减去从根到它们最近共同祖先的距离的两倍。

三、代码实现

//下面使用的遍历方法为前序遍历
public class Lca {
    // 1、构造二叉树
    public Node buildTree() {
        Node A = new Node('A');
        Node B = new Node('B');
        Node C = new Node('C');
        Node D = new Node('D');
        Node E = new Node('E');
        Node F = new Node('F');
        Node G = new Node('G');
        Node H = new Node('H');
        //这里是构造二叉树的关键
        A.left = B;
        A.right = C;
        B.left = D;
        B.right = E;
        C.left = F;
        C.right = G;
        E.right = H;
        return A;
    }

    //找两个结点最近的公共祖先
    public Node lowstCommonAncestor(Node root, Node p, Node q) {
        if (root == null) {
            return null;
        }
        if (root == p || root == q) {
            return root;
        }
        Node left = lowstCommonAncestor(root.left, p, q);
        Node right = lowstCommonAncestor(root.right, p, q);
        if (left != null && right != null) {
            return root;
        } else if (left != null) {
            return left;
        } else {
            return right;
        }
    }

    public static void main(String[] args) {
        Lca binaryTree = new Lca();
        Node root = binaryTree.buildTree();
        System.out.println(root);//这个是根即A的地址:com.xxp.common.algorithms.Node@5f4da5c3
        //这里打印出的是地址,可推断该公共祖先是A。与上面比较会发现是一致的
        System.out.println("找两个结点最近的公共祖先:" + binaryTree.lowstCommonAncestor(root, root.left, root.right.left));
        System.out.println(binaryTree.lowstCommonAncestor(root, root.left, root.right.left).val);
        System.out.println(root.val);

    }
}

class Node {
    public char val;
    public Node left;//左孩子
    public Node right;//右孩子

    public Node(char val) {
        this.val = val;
    }
}
  • 1
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
下面是一段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 方法计算给节点到目标节点的距离。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

JFS_Study

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

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

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

打赏作者

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

抵扣说明:

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

余额充值