zoukankan      html  css  js  c++  java
  • 寻找二叉树两个节点的最低公共祖先

    从root开始遍历,如果n1和n2中的任一个和root匹配,那么root就是LCA。 如果都不匹配,则分别递归左、右子树,如果有一个 key(n1或n2)出现在左子树,并且另一个key(n1或n2)出现在右子树,则root就是LCA.  如果两个key都出现在左子树,则说明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和n2的 LCA的指针
    // 假设n1和n2都出现在树中
    struct Node *findLCA(struct Node* root, int n1, int n2)
    {
        if (root == NULL) return NULL;
    
        // 只要n1 或 n2 的任一个匹配即可
        //  (注意:如果 一个节点是另一个祖先,则返回的是祖先节点。因为递归是要返回到祖先的 )
        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);
        // 如果都返回非空指针 Non-NULL, 则说明两个节点分别出现了在两个子树中,则当前节点肯定为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 << "
    LCA(4, 6) = " << findLCA(root, 4, 6)->key;
        cout << "
    LCA(3, 4) = " << findLCA(root, 3, 4)->key;
        cout << "
    LCA(2, 4) = " << findLCA(root, 2, 4)->key;
        return 0;
    }

    时间复杂度为O(n),但是上面的方法还是有所局限的,必须保证两个要查找的节点n1和n2都出现在树中。如果n1不在树中,则会返回n2为LCA,理想答案应该为NULL。要解决这个问题,可以先查找下 n1和n2是否出现在树中,然后加几个判断即可。

  • 相关阅读:
    ES6中变量的解析赋值的用途
    ES6中的Set与Map数据结构
    cocos2d-js 序列帧动画
    cocos2d-x坐标系详解
    【javascript】函数中的this的四种绑定形式
    ECMAScript 定义类、对象
    JS中函数参数值传递和引用传递
    作用域
    List<Map>如何根据Map的特定key对应的value对List排序?
    SQL字符型字段按数字型字段排序实现方法
  • 原文地址:https://www.cnblogs.com/kernel0815/p/5158193.html
Copyright © 2011-2022 走看看