• Lowest Common Ancestor in a Binary Tree


    二叉树最低公共祖先节点

    acmblog

    If one key is present and other is absent, then it returns the present key as LCA (Ideally should have returned NULL).
    We can extend this method to handle all cases by passing two boolean variables v1 and v2. v1 is set as true when n1 is present in tree and v2 is set as true if n2 is present in tree.

    /* C++ program to find LCA of n1 and n2 using one traversal of Binary Tree. 
    It handles all cases even when n1 or n2 is not there in Binary Tree */
    #include <iostream> 
    using namespace std; 
    
    // A Binary Tree Node 
    struct Node 
    { 
        struct Node *left, *right; 
        int key; 
    }; 
    
    // Utility function to create a new tree Node 
    Node* newNode(int key) 
    { 
        Node *temp = new Node; 
        temp->key = key; 
        temp->left = temp->right = NULL; 
        return temp; 
    } 
    
    // This function returns pointer to LCA of two given values n1 and n2. 
    // v1 is set as true by this function if n1 is found 
    // v2 is set as true by this function if n2 is found 
    struct Node *findLCAUtil(struct Node* root, int n1, int n2, bool &v1, bool &v2) 
    { 
        // Base case 
        if (root == NULL) return NULL; 
    
        // If either n1 or n2 matches with root's key, report the presence 
        // by setting v1 or v2 as true and return root (Note that if a key 
        // is ancestor of other, then the ancestor key becomes LCA) 
        if (root->key == n1) 
        { 
            v1 = true; 
            return root; 
        } 
        if (root->key == n2) 
        { 
            v2 = true; 
            return root; 
        } 
    
        // Look for keys in left and right subtrees 
        Node *left_lca = findLCAUtil(root->left, n1, n2, v1, v2); 
        Node *right_lca = findLCAUtil(root->right, n1, n2, v1, v2); 
    
        // If both of the above calls return Non-NULL, then one key 
        // is present in once subtree and other is present in other, 
        // So this node is the LCA 
        if (left_lca && right_lca) return root; 
    
        // Otherwise check if left subtree or right subtree is LCA 
        return (left_lca != NULL)? left_lca: right_lca; 
    } 
    
    // Returns true if key k is present in tree rooted with root 
    bool find(Node *root, int k) 
    { 
        // Base Case 
        if (root == NULL) 
            return false; 
    
        // If key is present at root, or in left subtree or right subtree, 
        // return true; 
        if (root->key == k || find(root->left, k) || find(root->right, k)) 
            return true; 
    
        // Else return false 
        return false; 
    } 
    
    // This function returns LCA of n1 and n2 only if both n1 and n2 are present 
    // in tree, otherwise returns NULL; 
    Node *findLCA(Node *root, int n1, int n2) 
    { 
        // Initialize n1 and n2 as not visited 
        bool v1 = false, v2 = false; 
    
        // Find lca of n1 and n2 using the technique discussed above 
        Node *lca = findLCAUtil(root, n1, n2, v1, v2); 
    
        // Return LCA only if both n1 and n2 are present in tree 
        if (v1 && v2 || v1 && find(lca, n2) || v2 && find(lca, n1)) 
            return lca; 
    
        // Else return NULL 
        return NULL; 
    } 
    
    // Driver program to test above functions 
    int main() 
    { 
        // Let us create binary tree given in the above example 
        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); 
        Node *lca = findLCA(root, 4, 5); 
        if (lca != NULL) 
        cout << "LCA(4, 5) = " << lca->key; 
        else
        cout << "Keys are not present "; 
    
        lca = findLCA(root, 4, 10); 
        if (lca != NULL) 
        cout << "nLCA(4, 10) = " << lca->key; 
        else
        cout << "nKeys are not present "; 
    
        return 0; 
    }
  • 相关阅读:
    Linux 常用工具openssh之ssh-copy-id
    Linux 常用工具openssh之ssh-agent
    SpringMVC视图机制详解[附带源码分析]
    Spring中Ordered接口简介
    SpringMVC拦截器详解[附带源码分析]
    SpringMVC类型转换、数据绑定详解[附带源码分析]
    详解SpringMVC请求的时候是如何找到正确的Controller[附带源码分析]
    详解SpringMVC中Controller的方法中参数的工作原理[附带源码分析]
    SpringMVC关于json、xml自动转换的原理研究[附带源码分析]
    Servlet容器Tomcat中web.xml中url-pattern的配置详解[附带源码分析]
  • 原文地址:https://www.cnblogs.com/guxuanqing/p/6063528.html
Copyright © 2020-2023  润新知