📌  相关文章
📜  删除连接到节点的边,以使三个给定节点位于不同的树中

📅  最后修改于: 2021-04-17 13:38:53             🧑  作者: Mango

给定一棵二叉树和3个节点a,b和c,任务是在树中找到一个节点,以便在除去连接到该节点的所有边缘之后,a,b和c位于三个不同的树中。

下面给出的是一棵输入节点为c,j和o的树。
示例树

在上面的树中,如果节点i与树断开连接,则给定的节点c,j和o将位于三棵不同的树中,如下所示。

从选定节点上移除了边缘的树

一种简单的方法是查找给定所有可能的节点对的LCA。
让,

  • (a,b)的lca = x
  • (b,c)= y的lca
  • (c,a)的lca = z

在任何情况下,(x,y),(y,z),(z,x)或(x,y,z)中的任何一个都将始终相同。在前三种情况下,返回不相同的节点。在最后一种情况下,返回x,y或z的任何节点都将给出答案。

下面是上述方法的实现:

C++
// C++ program for disconnecting a
// node to result in three different tree
#include 
using namespace std;
  
// node class
struct Node {
    int key;
    struct Node *left, *right;
};
Node* newNode(int key)
{
    Node* temp = new Node;
    temp->key = key;
    temp->left = temp->right = NULL;
    return (temp);
}
  
// LCA function taken from the above link mentioned
// This function returns a pointer to LCA of two given
// values n1 and n2. This function assumes that n1 and n2
// are present in Binary Tree
struct Node* findLCA(struct Node* root, int n1, int n2)
{
    // Base case
    if (root == NULL)
        return NULL;
  
    // If either n1 or n2 matches with root's key, report
    // the presence by returning root (Note that if a key is
    // ancestor of other, then the ancestor key becomes LCA
    if (root->key == n1 || root->key == n2)
        return root;
  
    // Look for keys in left and right subtrees
    Node* left_lca = findLCA(root->left, n1, n2);
    Node* right_lca = findLCA(root->right, n1, n2);
  
    // 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;
}
  
// the function assumes a, b, c are present in the tree
// and returns a node disconnecting which
// results in all three nodes in different trees
Node* findNode(Node* root, int a, int b, int c)
{
    // lca of a, b
    Node* x = findLCA(root, a, b);
  
    // lca of b, c
    Node* y = findLCA(root, b, c);
  
    // lca of c, a
    Node* z = findLCA(root, c, a);
  
    if (x->key == y->key)
        return z;
    else if (x->key == z->key)
        return y;
    else
        return x;
}
  
// Driver Code
int main()
{
    // Declare tree
    // Insert elements in the tree
    Node* root = newNode(1);
  
    root->left = newNode(2);
    root->right = newNode(3);
  
    root->left->left = newNode(4);
    root->left->right = newNode(5);
  
    root->left->left->left = newNode(8);
    root->left->left->right = newNode(9);
  
    root->left->right->left = newNode(10);
    root->left->right->right = newNode(11);
  
    root->right->left = newNode(6);
    root->right->right = newNode(7);
    root->right->left->left = newNode(12);
    root->right->left->right = newNode(13);
    root->right->right->left = newNode(14);
    root->right->right->right = newNode(15);
  
    /*
            1
        /     \
       2       3
     /  \     /  \
    4   5     6    7
   /\  / \   / \  / \
  8 9 10 11 12 13 14 15     
                           */
  
    // update all the suitable_children
    // keys of all the nodes in O( N )
  
    cout << "Disconnect node "
         << findNode(root, 5, 6, 15)->key
         << " from the tree";
  
    return 0;
}


Java
// Java program for disconnecting a 
// node to result in three different tree 
public class RemoveEdge {
  
    // LCA function taken from the above link mentioned 
    // This function returns a pointer to LCA of two given 
    // values n1 and n2. This function assumes that n1 and n2 
    // are present in Binary Tree 
    static Node findLCA(Node root, int n1, int n2) 
    { 
        // Base case 
        if (root == null) 
            return root; 
    
        // If either n1 or n2 matches with root's key, report 
        // the presence by returning root (Note that if a key is 
        // ancestor of other, then the ancestor key becomes LCA 
        if (root.key == n1 || root.key == n2) 
            return root; 
    
        // Look for keys in left and right subtrees 
        Node left_lca = findLCA(root.left, n1, n2); 
        Node right_lca = findLCA(root.right, n1, n2); 
    
        // 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!=null && right_lca!=null) 
            return root; 
    
        // Otherwise check if left subtree or right subtree is LCA 
        return (left_lca != null) ? left_lca : right_lca; 
    } 
    
    // the function assumes a, b, c are present in the tree 
    // and returns a node disconnecting which 
    // results in all three nodes in different trees 
    static Node findNode(Node root, int a, int b, int c) 
    { 
        // lca of a, b 
        Node x = findLCA(root, a, b); 
        // lca of b, c 
        Node y = findLCA(root, b, c); 
        // lca of c, a 
        Node z = findLCA(root, c, a); 
    
        if (x.key == y.key) 
            return z; 
        else if (x.key == z.key) 
            return y; 
        else
            return x; 
    } 
  
    public static void main(String args[]) {
        Node root = new Node(1); 
        root.left = new Node(2); 
        root.right = new Node(3); 
        root.left.left = new Node(4); 
        root.left.right = new Node(5); 
        root.left.left.left = new Node(8); 
        root.left.left.right = new Node(9); 
        root.left.right.left = new Node(10); 
        root.left.right.right = new Node(11); 
        root.right.left = new Node(6); 
        root.right.right = new Node(7); 
        root.right.left.left = new Node(12); 
        root.right.left.right = new Node(13); 
        root.right.right.left = new Node(14); 
        root.right.right.right = new Node(15); 
        System.out.print("Disconnect node "+findNode(root, 5, 6, 15).key+" from the tree");
    }
}
  
// Node class 
class Node { 
    int key; 
    Node left, right; 
    Node (int data)
    {
        this.key=data;
    }
}; 
//This code is contributed by Gaurav Tiwari


C#
// C# program for disconnecting a 
// node to result in three different tree 
using System;
  
public class RemoveEdge
{ 
  
    // LCA function taken from the 
    // above link mentioned This function
    // returns a pointer to LCA of two given 
    // values n1 and n2. This function
    // assumes that n1 and n2 
    // are present in Binary Tree 
    static Node findLCA(Node root, int n1, int n2) 
    { 
        // Base case 
        if (root == null) 
            return root; 
      
        // If either n1 or n2 matches 
        // with root's key, report 
        // the presence by returning 
        // root (Note that if a key is 
        // ancestor of other, then the 
        // ancestor key becomes LCA 
        if (root.key == n1 || root.key == n2) 
            return root; 
      
        // Look for keys in left and right subtrees 
        Node left_lca = findLCA(root.left, n1, n2); 
        Node right_lca = findLCA(root.right, n1, n2); 
      
        // 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!=null && right_lca!=null) 
            return root; 
      
        // Otherwise check if left 
        // subtree or right subtree is LCA 
        return (left_lca != null) ? left_lca : right_lca; 
    } 
      
    // the function assumes a, b, c 
    // are present in the tree and returns
    // a node disconnecting which results
    // in all three nodes in different trees 
    static Node findNode(Node root, int a, int b, int c) 
    { 
        // lca of a, b 
        Node x = findLCA(root, a, b); 
          
        // lca of b, c 
        Node y = findLCA(root, b, c); 
          
        // lca of c, a 
        Node z = findLCA(root, c, a); 
      
        if (x.key == y.key) 
            return z; 
        else if (x.key == z.key) 
            return y; 
        else
            return x; 
    } 
  
    // Driver code
    public static void Main(String []args) 
    { 
        Node root = new Node(1); 
        root.left = new Node(2); 
        root.right = new Node(3); 
        root.left.left = new Node(4); 
        root.left.right = new Node(5); 
        root.left.left.left = new Node(8); 
        root.left.left.right = new Node(9); 
        root.left.right.left = new Node(10); 
        root.left.right.right = new Node(11); 
        root.right.left = new Node(6); 
        root.right.right = new Node(7); 
        root.right.left.left = new Node(12); 
        root.right.left.right = new Node(13); 
        root.right.right.left = new Node(14); 
        root.right.right.right = new Node(15); 
        Console.Write("Disconnect node "+
                        findNode(root, 5, 6, 15).key+
                        " from the tree"); 
    } 
} 
  
// Node class 
public class Node 
{ 
    public int key; 
    public Node left, right; 
    public Node (int data) 
    { 
        this.key=data; 
    } 
}; 
  
// This code contributed by Rajput-Ji


输出:
Disconnect node 3 from the tree