Check if removing an edge can divide a Binary Tree in two halves

Given a Binary Tree, find if there exist edge whose removal creates two trees of equal size.

Examples:

Input : root of following tree
           5
         /   \
       1      6    
      /      /  \
     3      7    4
Output : true
Removing edge 5-6 creates two trees of equal size


Input : root of following tree
           5
         /   \
       1      6    
            /  \
           7    4
         /  \    \
        3    2    8
Output : false
There is no edge whose removal creates two trees
of equal size.

Source- Kshitij IIT KGP

 

Method 1 (Simple)
First count number of nodes in whole tree. Let count of all nodes be n. Now traverse tree and for every node, find size of subtree rooted with this node. Let the subtree size be s. If n-s is equal to s, then return true, else false.

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to check if there exist an edge whose
// removal creates two trees of same size
#include<bits/stdc++.h>
using namespace std;
  
struct Node
{
    int data;
    struct Node* left, *right;
};
  
// utility function to create a new node
struct Node* newNode(int x)
{
    struct Node* temp = new Node;
    temp->data = x;
    temp->left = temp->right = NULL;
    return temp;
};
  
// To calculate size of tree with given root
int count(Node* root)
{
    if (root==NULL)
        return 0;
    return count(root->left) + count(root->right) + 1;
}
  
// This function returns true if there is an edge
// whose removal can divide the tree in two halves
// n is size of tree
bool checkRec(Node* root, int n)
{
    // Base cases
    if (root ==NULL)
       return false;
  
    // Check for root
    if (count(root) == n-count(root))
        return true;
  
    // Check for rest of the nodes
    return checkRec(root->left, n) ||
           checkRec(root->right, n);
}
  
// This function mainly uses checkRec()
bool check(Node *root)
{
    // Count total nodes in given tree
    int n = count(root);
  
    // Now recursively check all nodes
    return checkRec(root, n);
}
  
// Driver code
int main()
{
    struct Node* root = newNode(5);
    root->left = newNode(1);
    root->right = newNode(6);
    root->left->left = newNode(3);
    root->right->left = newNode(7);
    root->right->right = newNode(4);
  
    check(root)?  printf("YES") : printf("NO");
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to check if there exist an edge whose
// removal creates two trees of same size
  
class Node 
{
    int key;
    Node left, right;
  
    public Node(int key) 
    {
        this.key = key;
        left = right = null;
    }
}
  
class BinaryTree 
{
    Node root;
  
    // To calculate size of tree with given root
    int count(Node node) 
    {
        if (node == null)
            return 0;
          
        return count(node.left) + count(node.right) + 1;
    }
  
    // This function returns true if there is an edge
    // whose removal can divide the tree in two halves
    // n is size of tree
    boolean checkRec(Node node, int n) 
    {
        // Base cases
        if (node == null
            return false;
  
        // Check for root
        if (count(node) == n - count(node))
            return true;
  
        // Check for rest of the nodes
        return checkRec(node.left, n)
                || checkRec(node.right, n);
    }
  
    // This function mainly uses checkRec()
    boolean check(Node node) 
    {
        // Count total nodes in given tree
        int n = count(node);
  
        // Now recursively check all nodes
        return checkRec(node, n);
    }
  
    // Driver code
    public static void main(String[] args) 
    {
        BinaryTree tree = new BinaryTree();
        tree.root = new Node(5);
        tree.root.left = new Node(1);
        tree.root.right = new Node(6);
        tree.root.left.left = new Node(3);
        tree.root.right.left = new Node(7);
        tree.root.right.right = new Node(4);
        if(tree.check(tree.root)==true)
            System.out.println("YES");
        else
            System.out.println("NO");
    }
}
  
// This code has been contributed by Mayank Jaiswal(mayank_24)

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to check if there 
# exist an edge whose removal creates
# two trees of same size 
  
# utility function to create a new node 
class newNode:
    def __init__(self, x):
        self.data =
        self.left = self.right = None
  
# To calculate size of tree 
# with given root 
def count(root):
    if (root == None):
        return 0
    return (count(root.left) + 
            count(root.right) + 1)
  
# This function returns true if there 
# is an edge whose removal can divide 
# the tree in two halves n is size of tree 
def checkRec(root, n):
      
    # Base cases 
    if (root == None): 
        return False
  
    # Check for root 
    if (count(root) == n - count(root)):
        return True
  
    # Check for rest of the nodes 
    return (checkRec(root.left, n) or 
            checkRec(root.right, n))
  
# This function mainly uses checkRec() 
def check(root):
      
    # Count total nodes in given tree 
    n = count(root) 
  
    # Now recursively check all nodes 
    return checkRec(root, n)
  
# Driver code 
if __name__ == '__main__':
    root = newNode(5
    root.left = newNode(1
    root.right = newNode(6
    root.left.left = newNode(3
    root.right.left = newNode(7
    root.right.right = newNode(4
  
    if check(root):
        print("YES")
    else
        print("NO")
          
# This code is contributed by PranchalK

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to check if there exist 
// an edge whose removal creates two 
// trees of same size 
using System;
  
public class Node
{
    public int key;
    public Node left, right;
  
    public Node(int key)
    {
        this.key = key;
        left = right = null;
    }
}
  
class GFG
{
public Node root;
  
// To calculate size of tree with given root 
public virtual int count(Node node)
{
    if (node == null)
    {
        return 0;
    }
  
    return count(node.left) +
           count(node.right) + 1;
}
  
// This function returns true if there 
// is an edge whose removal can divide 
// the tree in two halves n is size of tree 
public virtual bool checkRec(Node node, int n)
{
    // Base cases 
    if (node == null)
    {
        return false;
    }
  
    // Check for root 
    if (count(node) == n - count(node))
    {
        return true;
    }
  
    // Check for rest of the nodes 
    return checkRec(node.left, n) || 
           checkRec(node.right, n);
}
  
// This function mainly uses checkRec() 
public virtual bool check(Node node)
{
    // Count total nodes in given tree 
    int n = count(node);
  
    // Now recursively check all nodes 
    return checkRec(node, n);
}
  
// Driver code 
public static void Main(string[] args)
{
    GFG tree = new GFG();
    tree.root = new Node(5);
    tree.root.left = new Node(1);
    tree.root.right = new Node(6);
    tree.root.left.left = new Node(3);
    tree.root.right.left = new Node(7);
    tree.root.right.right = new Node(4);
    if (tree.check(tree.root) == true)
    {
        Console.WriteLine("YES");
    }
    else
    {
        Console.WriteLine("NO");
    }
}
}
  
// This code is contributed by Shrikant13

chevron_right



Output :

YES

Time complexity of above solution is O(n2) where n is number of nodes in given Binary Tree.

 
 
Method 2 (Efficient)
We can find the solution in O(n) time. The idea is to traverse tree in bottom up manner and while traversing keep updating size and keep checking if there is a node that follows the required property.

Below is the implementation of above idea.

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to check if there exist an edge whose
// removal creates two trees of same size
#include<bits/stdc++.h>
using namespace std;
  
struct Node
{
    int data;
    struct Node* left, *right;
};
  
// utility function to create a new node
struct Node* newNode(int x)
{
    struct Node* temp = new Node;
    temp->data = x;
    temp->left = temp->right = NULL;
    return temp;
};
  
// To calculate size of tree with given root
int count(Node* root)
{
    if (root==NULL)
        return 0;
    return count(root->left) + count(root->right) + 1;
}
  
// This function returns size of tree rooted with given
// root. It also set "res" as true if there is an edge
// whose removal divides tree in two halves.
// n is size of tree
int checkRec(Node* root, int n, bool &res)
{
    // Base case
    if (root == NULL)
       return 0;
  
    // Compute sizes of left and right children
    int c = checkRec(root->left, n, res) + 1 +
            checkRec(root->right, n, res);
  
    // If required property is true for current node
    // set "res" as true
    if (c == n-c)
        res = true;
  
    // Return size
    return c;
}
  
// This function mainly uses checkRec()
bool check(Node *root)
{
    // Count total nodes in given tree
    int n = count(root);
  
    // Initialize result and recursively check all nodes
    bool res = false;
    checkRec(root, n,  res);
  
    return res;
}
  
// Driver code
int main()
{
    struct Node* root = newNode(5);
    root->left = newNode(1);
    root->right = newNode(6);
    root->left->left = newNode(3);
    root->right->left = newNode(7);
    root->right->right = newNode(4);
  
    check(root)?  printf("YES") : printf("NO");
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to check if there exist an edge whose
// removal creates two trees of same size
  
class Node 
{
    int key;
    Node left, right;
  
    public Node(int key) 
    {
        this.key = key;
        left = right = null;
    }
}
  
class Res 
{
    boolean res = false;
}
  
class BinaryTree 
{
    Node root;
  
    // To calculate size of tree with given root
    int count(Node node) 
    {
        if (node == null)
            return 0;
  
        return count(node.left) + count(node.right) + 1;
    }
  
    // This function returns size of tree rooted with given
    // root. It also set "res" as true if there is an edge
    // whose removal divides tree in two halves.
    // n is size of tree
    int checkRec(Node root, int n, Res res) 
    {
        // Base case
        if (root == null)
            return 0;
         
        // Compute sizes of left and right children
        int c = checkRec(root.left, n, res) + 1
                + checkRec(root.right, n, res);
  
        // If required property is true for current node
        // set "res" as true
        if (c == n - c) 
            res.res = true;
  
        // Return size
        return c;
    }
  
    // This function mainly uses checkRec()
    boolean check(Node root) 
    {
        // Count total nodes in given tree
        int n = count(root);
  
        // Initialize result and recursively check all nodes
        Res res = new Res();
        checkRec(root, n, res);
  
        return res.res;
    }
  
    // Driver code
    public static void main(String[] args) 
    {
        BinaryTree tree = new BinaryTree();
        tree.root = new Node(5);
        tree.root.left = new Node(1);
        tree.root.right = new Node(6);
        tree.root.left.left = new Node(3);
        tree.root.right.left = new Node(7);
        tree.root.right.right = new Node(4);
        if (tree.check(tree.root) == true)
            System.out.println("YES");
        else
            System.out.println("NO");
    }
}
  
// This code has been contributed by Mayank Jaiswal(mayank_24)

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

using System;
  
// C# program to check if there exist an edge whose 
// removal creates two trees of same size 
  
public class Node
{
    public int key;
    public Node left, right;
  
    public Node(int key)
    {
        this.key = key;
        left = right = null;
    }
}
  
public class Res
{
    public bool res = false;
}
  
public class BinaryTree
{
    public Node root;
  
    // To calculate size of tree with given root 
    public virtual int count(Node node)
    {
        if (node == null)
        {
            return 0;
        }
  
        return count(node.left) + count(node.right) + 1;
    }
  
    // This function returns size of tree rooted with given 
    // root. It also set "res" as true if there is an edge 
    // whose removal divides tree in two halves. 
    // n is size of tree 
    public virtual int checkRec(Node root, int n, Res res)
    {
        // Base case 
        if (root == null)
        {
            return 0;
        }
  
        // Compute sizes of left and right children 
        int c = checkRec(root.left, n, res) + 1 + checkRec(root.right, n, res);
  
        // If required property is true for current node 
        // set "res" as true 
        if (c == n - c)
        {
            res.res = true;
        }
  
        // Return size 
        return c;
    }
  
    // This function mainly uses checkRec() 
    public virtual bool check(Node root)
    {
        // Count total nodes in given tree 
        int n = count(root);
  
        // Initialize result and recursively check all nodes 
        Res res = new Res();
        checkRec(root, n, res);
  
        return res.res;
    }
  
    // Driver code 
    public static void Main(string[] args)
    {
        BinaryTree tree = new BinaryTree();
        tree.root = new Node(5);
        tree.root.left = new Node(1);
        tree.root.right = new Node(6);
        tree.root.left.left = new Node(3);
        tree.root.right.left = new Node(7);
        tree.root.right.right = new Node(4);
        if (tree.check(tree.root) == true)
        {
            Console.WriteLine("YES");
        }
        else
        {
            Console.WriteLine("NO");
        }
    }
}
  
  // This code is contributed by Shrikant13

chevron_right



Output :

YES

This article is contributed by Asaad Akram. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above



My Personal Notes arrow_drop_up



Article Tags :
Practice Tags :


5


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.