最小公共祖先

对二叉查找树找到两个节点的最小公共祖先:可以根据二叉查找树的性质:左子树的节点值比根节点的值小,右子树的节点值比根节点值大

public class BinarySearchTree<T extends Comparable> {
    BinaryTreeNode<T> root;
    public BinarySearchTree(BinaryTreeNode<T> root) {
      this.root = root;
    }
    public BinaryTreeNode<T> getRoot() {
      return root;
    }

    /*
     * 两个不同节点的最小祖先 思路: left比root节点大, 遍历root的右子树,max比root节点小,遍历root左子树
     * 不满足以上情况表示找到他们的祖先,并返回
     */
    public T getLowestCommonAncestor(T n1, T n2) {    //分别以递归和非递归实现
      //return findNodeWithNoCursion(root, n1, n2);
      return findNodeWithCursion(root, n1, n2);
    }

    private T findNodeWithCursion(BinaryTreeNode<T> node, T n1, T n2) {
      if (node == null) {
          return null;
      }
      if (n1.compareTo(node.data) < 0 && n2.compareTo(node.data) < 0) {
          return findNodeWithCursion(node.left, n1, n2);
      }
      if (n1.compareTo(node.data) > 0 && n2.compareTo(node.data) > 0) {
          return findNodeWithCursion(node.right, n1, n2);
      }
      return node.data;
    }

    private T findNodeWithNoCursion(BinaryTreeNode<T> node, T n1, T n2) {    //若n1 > n2, 调换位置
      if (n1.compareTo(n2) > 0) {
          T tmp = n1;
          n1 = n2;
          n2 = tmp;
      }  
      while (true) {
          if (n1.compareTo(node.data) > 0) {
            node = node.right;
          } else if (n2.compareTo(node.data) < 0) {
            node = node.left;
          } else {
            return node.data;
          }
      }
    }  
  public static void main(String[] args) {
      BinaryTreeNode<Integer> root = new BinaryTreeNode<Integer>(5);
      root.left = new BinaryTreeNode<Integer>(2);
      root.right = new BinaryTreeNode<Integer>(6);
      root.left.left = new BinaryTreeNode<Integer>(1);
      root.left.right = new BinaryTreeNode<Integer>(4);
      root.left.right.left = new BinaryTreeNode<Integer>(3);
      BinarySearchTree<Integer> tree = new BinarySearchTree<Integer>(root);
        System.out.println(tree.getLowestCommonAncestor(1, 6));    //5
    }    
}

以下是二叉树节点的类的定义

public class BinaryTreeNode<T extends Comparable> {

    public  T data;
    public  BinaryTreeNode<T> left;
    public  BinaryTreeNode<T> right;

    public BinaryTreeNode() {
    }

    public BinaryTreeNode(T data) {
    this.data = data;
    }

    public BinaryTreeNode(T data, BinaryTreeNode<T> right, BinaryTreeNode<T> left) {
      this.data = data;
      this.left = left;
      this.right = right;
    }

    public T getData() {
      return data;
    }

    public void setData(T data) {
      this.data = data;
    }

    public BinaryTreeNode<T> getLeft() {
      return left;
    }

    public void setLeft(BinaryTreeNode<T> left) {
      this.left = left;
    }

    public BinaryTreeNode<T> getRight() {
      return right;
    }

    public void setRight(BinaryTreeNode<T> right) {
      this.right = right;
    }
时间: 2025-01-12 23:06:26

最小公共祖先的相关文章

数据结构问题集锦 - 最小公共祖先问题

作为一个工程党,在各路竞赛大神的面前总会感到自己实力的捉急.大神总是能够根据问题的不同,轻而易举地给出问题的解法,然而我这种渣渣只能用所谓的”直观方法“聊以自慰,说多了都是泪啊.However,正视自己理论方面的不足,迎头赶上还是必要的,毕竟要真正踏入业界,理论知识是不能少的啊.(比如各种语言的Hash Map,它们的核心可都是红黑树啊) 既然助教要求博文要直观,通俗易懂,那就让我们递归这种方法开始.方法一:递归法 按照题目的要求,如果某两个节点具有同一个公共祖先的话,那么会存在两种情况:要么其

最小公共祖先lca

3.神秘国度的爱情故事 题目要求:某个太空神秘国度中有很多美丽的小村,从太空中可以想见,小村间有路相连,更精确一点说,任意两村之间有且仅有一条路径.小村 A 中有位年轻人爱上了自己村里的美丽姑娘.每天早晨,姑娘都会去小村 B 里的面包房工作,傍晚 6 点回到家.年轻人终于决定要向姑娘表白,他打算在小村 C 等着姑娘路过的时候把爱慕说出来.问题是,他不能确定小村 C 是否在小村 B 到小村 A 之间的路径上.你可以帮他解决这个问题吗? 输入要求:输入由若干组测试数据组成.每组数据的第 1 行包含一

二叉树的最小公共祖先问题

今天做了两个二叉树的题目, 挺简单的, 不用调试, 直接在提交框上敲完提交, 直接就通过了. 第一个题目是求二叉查找树的公共祖先, 因为是排序的, 所以很好做. 具体思路如下: 1 如果两个节点都比当前节点小, 那公共祖先必然是当前节点的左子树上, 所以递归左子树; 2 如果两个节点都比当前节点大, 那么同上, 递归右子树; 3 如果两个节点有一个为当前节点, 则当前节点为公共节点; 如果两个节点分别比当前节点小和大, 那么当前节点必为公共节点. 具体代码如下: class Solution {

LeetCode -- 查找最小公共祖先

在一棵二叉树中, 查找两个节点的最近的公共祖先.由于本题没有涉及到批量查询,因此考虑一般解法即可,如果涉及批量,可考虑Tarjan算法. 思路:1. 先序遍历2. 判断查找的两节点和当前节点的关系3. 根据是否为空的情况返回不同节点 要注意的地方是判断节点是否相等,本题使用了C++语言,直接判断指针本身了 /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * Tree

最近公共祖先(LCA)问题

描述 对于有根树T的两个节点u和v,最近公共祖先LCA(T,u,v)表示一个节点x满足x是u,v的公共祖先且x的深度尽可能大. 算法 求解LCA问题主要有三种解法,分别是暴力搜索,Tanjar算法,最后一种是转化为RMQ问题,用DFS+ST算法来求解 暴力搜索 如果数据量不大的时候可以采用暴力搜索法.先将节点u的祖先节点全部标记出来,然后顺着节点v沿着父亲节点的方向向上遍历,直到遍历到一个被标记的节点,这个节点即为所求节点.或者分别获取u,v到根节点的路径P1,P2,可以将这两条路径看做两个两个

LCA(最近公共祖先)——离线 Tarjan 算法

一.梳理概念 定义:对于有根树T的两个结点u.v,最近公共祖先LCA(T,u,v)表示一个结点x,满足x是u.v的祖先且x的深度尽可能大. 通俗地讲,最近公共祖先节点,就是两个节点在这棵树上深度最大的公共的祖先节点,即两个点在这棵树上距离最近的公共祖先节点. 提示:父亲节点也是祖先节点,节点本身也是它的祖先节点. 给出一棵树,如图所示: 由上面的定义可知:3和5的最近公共祖先为1,5和6的最近公共祖先为2,2和7的最近公共祖先为2, 6和7的最近公共祖先为4. 二.繁文缛节 注意注意注意!!!尚

亚马逊 在线测试题目 amazon (变种的)三叉树的最近公共祖先问题

题目意思就是找一棵按上面链接所示的树对应的上面的两个点的最小公共祖先(LCP,Least Common Father),按照比较大小来依次返回自己的父亲节点就行了.具体看代码:getfather(a)函数是找父亲的代码 #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxDepth = 2

二叉树中两个结点最近的公共祖先汇总

一.若二叉树为搜索二叉树 原题链接:https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/#/description Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST. According to the definition of LCA on

最近公共祖先

0. 概要 最近公共祖先,指的是在一颗有根树上,两个点的公共祖先中,深度最大的那个. 最直接的应用是求无权树上两个点的最短距离:$distance(u, v)  = depth(u) + depth(v) - 2depth(lca(u, v))$. 再有其他的应用则以后再提. 1 基于 dfs 序列上 RMQ 的稀疏表解法 首先 dfs 遍历树,如下如图中蓝色箭头的顺序.并记录: 1. 遍历点序列 $euler[] = \{1, 2, 1, 3, 5, 3, 6 ……$ 2. 每个点首次在 eu