二叉树:找出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