树---求给定二叉树中两节点的最低公共祖先(LCA)

来源:互联网 发布:centos安装intellij 编辑:程序博客网 时间:2024/05/29 17:31

一、问题描述

对于一颗二叉树,给定其中的两节点n1,n2,求出他们的最低公共祖先(Lowest Common Ancestor )。例如:
这里写图片描述

二、问题求解

利用递归思想。

1)从root开始遍历,如果n1和n2中的任一个和root匹配,那么root就是LCA。(2) 如果都不匹配,则分别递归左、右子树,如果有一个 key(n1或n2)出现在左子树,并且另一个key(n1或n2)出现在右子树,则root就是LCA.  (3)如果两个key都出现在左子树,则说明LCA在左子树中,否则在右子树。

三、实现代码

时间复杂度为O(n)

#include<iostream>using namespace std;typedef int KeyType;typedef struct BinaryTreeNode{    KeyType key;    struct BinaryTreeNode *left;    struct BinaryTreeNode *right;}BTNode, *BiTree;//创建二叉树节点BTNode *CreateBTNode(KeyType key){    BTNode *node = new BTNode;    node->key = key;    node->left = node->right = NULL;    return node;}//对于给定的树中两节点n1和n2,返回两者lca的指针BTNode *findLCA(BTNode *root, KeyType n1, KeyType n2){    if(root == NULL) return NULL;    //(1)n1,n2中的一个是另一个的父节点,即为LCA    if(root->key==n1 || root->key==n2)        return root;    //(2)n1,n2没有父子关系,这时又存在两种情况:    //case1:同在一个子树。case2:分别在两个子树。    BTNode *left_lca=findLCA(root->left, n1, n2);    BTNode *right_lca=findLCA(root->right, n1, n2);    //都为真,说明两边子树都能找到n1或n2,这是case2的情况    if(left_lca && right_lca)        return root;//当n1,n2分别在两个子树时lca即为根节点    //case1的情况    return (left_lca != NULL)?left_lca:right_lca;}int main(){    BTNode *root = CreateBTNode(1);    root->left = CreateBTNode(2);    root->right = CreateBTNode(3);    root->left->left = CreateBTNode(4);    root->left->right = CreateBTNode(5);    root->right->left = CreateBTNode(6);    root->right->right = CreateBTNode(7);    cout <<"LCA(4, 5): "<<findLCA(root, 4, 5)->key<<endl;    cout <<"LCA(4, 6): "<<findLCA(root, 4, 6)->key<<endl;    cout <<"LCA(3, 4): "<<findLCA(root, 3, 4)->key<<endl;    cout <<"LCA(2, 4): "<<findLCA(root, 2, 4)->key<<endl;    return 0;}

结果:

LCA(4, 5): 2LCA(4, 6): 1LCA(3, 4): 1LCA(2, 4): 2Process returned 0 (0x0)   execution time : 0.279 sPress any key to continue.
0 0