Given a Binary Tree having odd and even elements, sink all its even valued nodes such that no node with an even value could be a parent of a node with an odd value.
There can be multiple outputs for a given tree, we need to print one of them. It is always possible to convert a tree (Note that a node with odd nodes and all even nodes follow the rule)
Examples:
Input: 1 / \ 5 8 / \ / \ 2 4 9 10 Output: 1 5 9 2 4 8 10 Level order traversal after sinking all the nodes Input: 4 / \ 2 1 Output: 4 2 1
Explanation: In the first case Given tree 4 / \ 2 1 There are two trees possible 1 1 / \ OR / \ 2 4 4 2 In the second example also, Given tree 1 / \ 5 8 / \ / \ 2 4 9 10 There are more than one tree that can satisfy the condition 1 1 / \ / \ 5 9 OR 5 9 / \ / \ / \ / \ 2 4 8 10 4 2 8 10
Approach:
- Basically, it is required to swap the even value of a node with the odd value of one of its descendants.
- The idea is to traverse the tree in a postorder fashion.
- Since we process in postorder, for each even node encountered, its left and right subtrees are already balanced (sinked).
- Check if it’s an even node and its left or right child has an odd value. If the odd value is found, swap the node’s data with that of the odd child node and call the procedure on the odd child to balance the subtree.
- If both children have even values, that means that all their descendants are even.
Below is the implementation of the idea:
C++
//C++ program for the above approach #include <bits/stdc++.h> using namespace std;
// A binary tree node struct Node {
int data;
Node *left, *right;
}; // Helper function to create a new node Node* newNode( int key)
{ Node* node = new Node;
node->data = key;
node->left = node->right = NULL;
return node;
} // Helper function to check // if node is leaf node bool isLeaf(Node* root)
{ return (root->left == NULL && root->right == NULL);
} // A recursive method to sink a tree with even root // This method assumes that the subtrees are // already sinked. This method is similar to // Heapify of Heap-Sort void sink(Node* root)
{ // If NULL or is a leaf, do nothing
if (root == NULL || isLeaf(root))
return ;
// if left subtree exists and
// left child is even
if (root->left && (root->left->data & 1)) {
// swap root's data with left child
// and fix left subtree
swap(root->data, root->left->data);
sink(root->left);
}
// if right subtree exists and
// right child is even
else if (root->right && (root->right->data & 1)) {
// swap root's data with right child
// and fix right subtree
swap(root->data, root->right->data);
sink(root->right);
}
} // Function to sink all even nodes to // the bottom of binary tree. It does // a postorder traversal and calls sink() // if any even node is found void sinkEvenNodes(Node* root)
{ // If NULL or is a leaf, do nothing
if (root == NULL || isLeaf(root))
return ;
// Process left and right subtrees
// before this node
sinkEvenNodes(root->left);
sinkEvenNodes(root->right);
// If root is even, sink it
if (!(root->data & 1))
sink(root);
} // Helper function to do Level Order Traversal // of Binary Tree level by level. This function // is used here only for showing modified tree. void printLevelOrder(Node* root)
{ queue<Node*> q;
q.push(root);
// Do Level order traversal
while (!q.empty()) {
int nodeCount = q.size();
// Print one level at a time
while (nodeCount) {
Node* node = q.front();
cout << node->data << " " ;
q.pop();
if (node->left != NULL)
q.push(node->left);
if (node->right != NULL)
q.push(node->right);
nodeCount--;
}
// Line separator for levels
cout << endl;
}
} int main()
{ /* Constructed binary tree is
1
/ \
5 8
/ \ / \
2 4 9 10 */
Node* root = newNode(1);
root->left = newNode(5);
root->right = newNode(8);
root->left->left = newNode(2);
root->left->right = newNode(4);
root->right->left = newNode(9);
root->right->right = newNode(10);
sinkEvenNodes(root);
printLevelOrder(root);
return 0;
} //This code is contributed by Potta Lokesh |
Java
import java.util.Queue;
import java.util.LinkedList;
// A binary tree node class Node {
int data;
Node left, right;
public Node( int data)
{
this .data = data;
left = right = null ;
}
} class Main
{ // Helper function to check
// if node is leaf node
static boolean isLeaf(Node root)
{
return (root.left == null && root.right == null );
}
// A recursive method to sink a tree with even root
// This method assumes that the subtrees are
// already sinked. This method is similar to
// Heapify of Heap-Sort
static void sink(Node root)
{
// If null or is a leaf, do nothing
if (root == null || isLeaf(root))
return ;
// if left subtree exists and
// left child is even
if (root.left != null && (root.left.data & 1 ) != 0 )
{
// swap root's data with left child
// and fix left subtree
//swap(root.data, root.left.data);
int temp = root.data;
root.data = root.left.data;
root.left.data = temp;
sink(root.left);
}
// if right subtree exists and
// right child is even
else if (root.right != null && (root.right.data & 1 ) != 0 )
{
// swap root's data with right child
// and fix right subtree
//swap(root.data, root.right.data);
int temp = root.data;
root.data = root.right.data;
root.right.data = temp;
sink(root.right);
}
}
// Function to sink all even nodes to
// the bottom of binary tree. It does
// a postorder traversal and calls sink()
// if any even node is found
static void sinkEvenNodes(Node root)
{
// If null or is a leaf, do nothing
if (root == null || isLeaf(root))
return ;
// Process left and right subtrees
// before this node
sinkEvenNodes(root.left);
sinkEvenNodes(root.right);
if ((root.data & 1 ) == 0 )
sink(root);
}
// Helper function to do Level Order Traversal
// of Binary Tree level by level. This function
// is used here only for showing modified tree.
static void printLevelOrder(Node root)
{
// Do Level order traversal
Queue<Node> q = new LinkedList<Node>();
q.add(root);
while (q.size() > 0 ) {
int nodeCount = q.size();
while (nodeCount > 0 ) {
Node node = q.peek();
System.out.print(node.data + " " );
q.remove();
if (node.left != null )
q.add(node.left);
if (node.right != null )
q.add(node.right);
nodeCount--;
}
System.out.println();
}
}
// Driver code
public static void main(String[] args)
{
Node root = new Node( 1 );
root.left = new Node( 5 );
root.right = new Node( 8 );
root.left.left = new Node( 2 );
root.left.right = new Node( 4 );
root.right.left = new Node( 9 );
root.right.right = new Node( 10 );
sinkEvenNodes(root);
printLevelOrder(root);
}
} // This code is contributed by unstoppablepandu. |
Python
# Python3 program to sink even nodes # to the bottom of binary tree # A binary tree node # Helper function to allocates a new node class newnode:
# Constructor to create a new node
def __init__( self , key):
self .data = key
self .left = None
self .right = None
# Helper function to check # if node is leaf node def isLeaf(root):
return (root.left = = None and
root.right = = None )
# A recursive method to sink a tree with even root # This method assumes that the subtrees are # already sinked. This method is similar to # Heapify of Heap-Sort def sink(root):
# If None or is a leaf, do nothing
if (root = = None or isLeaf(root)):
return
# if left subtree exists and
# left child is even
if (root.left and (root.left.data & 1 )):
# swap root's data with left child
# and fix left subtree
root.data, root.left.data = root.left.data, root.data
sink(root.left)
# if right subtree exists and
# right child is even
elif (root.right and (root.right.data & 1 )):
# swap root's data with right child
# and fix right subtree
root.data, root.right.data = root.right.data, root.data
sink(root.right)
# Function to sink all even nodes to # the bottom of binary tree. It does # a postorder traversal and calls sink() # if any even node is found def sinkevenNodes(root):
# If None or is a leaf, do nothing
if (root = = None or isLeaf(root)):
return
# Process left and right subtrees
# before this node
sinkevenNodes(root.left)
sinkevenNodes(root.right)
# If root is even, sink it
if not (root.data & 1 ):
sink(root)
# Helper function to do Level Order Traversal # of Binary Tree level by level. This function # is used here only for showing modified tree. def printLevelOrder(root):
q = []
q.append(root)
# Do Level order traversal
while ( len (q)):
nodeCount = len (q)
# Print one level at a time
while (nodeCount):
node = q[ 0 ]
print (node.data, end = " " )
q.pop( 0 )
if (node.left ! = None ):
q.append(node.left)
if (node.right ! = None ):
q.append(node.right)
nodeCount - = 1
# Line separator for levels
print ()
# Driver Code """ Constructed binary tree is 1
/ \
5 8
/ \ / \
2 4 9 10 """
root = newnode( 1 )
root.left = newnode( 5 )
root.right = newnode( 8 )
root.left.left = newnode( 2 )
root.left.right = newnode( 4 )
root.right.left = newnode( 9 )
root.right.right = newnode( 10 )
sinkevenNodes(root) printLevelOrder(root) # This code is contributed by SHUBHAMSINGH10 |
C#
// C# program for the above approach using System;
using System.Collections.Generic;
class GFG
{ // A binary tree node
class Node {
public int data;
public Node left, right;
}
// Helper function to create a new node
static Node newNode( int key)
{
Node node = new Node();
node.data = key;
node.left = node.right = null ;
return node;
}
// Helper function to check
// if node is leaf node
static bool isLeaf(Node root)
{
return (root.left == null && root.right == null );
}
// A recursive method to sink a tree with even root
// This method assumes that the subtrees are
// already sinked. This method is similar to
// Heapify of Heap-Sort
static void sink(Node root)
{
// If null or is a leaf, do nothing
if (root == null || isLeaf(root))
return ;
// if left subtree exists and
// left child is even
if (root.left != null && (root.left.data & 1) != 0)
{
// swap root's data with left child
// and fix left subtree
//swap(root.data, root.left.data);
int temp=root.data;
root.data=root.left.data;
root.left.data=temp;
sink(root.left);
}
// if right subtree exists and
// right child is even
else if (root.right != null && (root.right.data & 1) != 0)
{
// swap root's data with right child
// and fix right subtree
//swap(root.data, root.right.data);
int temp=root.data;
root.data=root.right.data;
root.right.data=temp;
sink(root.right);
}
}
// Function to sink all even nodes to
// the bottom of binary tree. It does
// a postorder traversal and calls sink()
// if any even node is found
static void sinkEvenNodes(Node root)
{
// If null or is a leaf, do nothing
if (root == null || isLeaf(root))
return ;
// Process left and right subtrees
// before this node
sinkEvenNodes(root.left);
sinkEvenNodes(root.right);
// If root is even, sink it
if ((root.data & 1)==0)
sink(root);
}
// Helper function to do Level Order Traversal
// of Binary Tree level by level. This function
// is used here only for showing modified tree.
static void printLevelOrder(Node root)
{
Queue<Node> q = new Queue<Node>();
q.Enqueue(root);
// Do Level order traversal
while (q.Count>0) {
int nodeCount = q.Count;
// Print one level at a time
while (nodeCount>0) {
Node node = q.Peek();
Console.Write(node.data+ " " );
q.Dequeue();
if (node.left != null )
q.Enqueue(node.left);
if (node.right != null )
q.Enqueue(node.right);
nodeCount--;
}
// Line separator for levels
Console.Write( "\n" );
}
}
static void Main( string [] args)
{
/* Constructed binary tree is
1
/ \
5 8
/ \ / \
2 4 9 10 */
Node root = newNode(1);
root.left = newNode(5);
root.right = newNode(8);
root.left.left = newNode(2);
root.left.right = newNode(4);
root.right.left = newNode(9);
root.right.right = newNode(10);
sinkEvenNodes(root);
printLevelOrder(root);
}
} // This code is contributed by poojaagarwal2. |
Javascript
<script> // Program to sink even nodes // to the bottom of binary tree // A binary tree node class Node { constructor()
{
this .data = 0;
this .left = null ;
this .right = null ;
}
}; // Helper function to allocates // a new node function newnode(data)
{ var node = new Node;
node.data = data;
return node;
} // Helper function to check // if node is leaf node function isLeaf(root)
{ return (root.left == null
&& root.right == null );
} // A recursive method to sink // a tree with odd root // This method assumes that the // subtrees are already sinked. // This method is similar to // Heapify of Heap-Sort function sink(root)
{ // If null or is a leaf, do nothing
if (root == null || isLeaf(root))
return ;
// If left subtree exists
// and left child is odd
if (root.left
&& (root.left.data & 1)) {
// Swap root's data with left
// child and fix left subtree
[root.data,
root.left.data] = [root.left.data, root.data];
sink(root.left);
}
// If right subtree exists
// and right child is odd
else if (root.right
&& (root.right.data & 1)) {
// Swap root's data with right
// child and fix right subtree
[root.data,
root.right.data] = [root.right.data, root.data];
sink(root.right);
}
} // Function to sink all even // nodes to the bottom of // binary tree. It does a // postorder traversal and // calls sink() // if any even node is found function sinkevenNodes( root)
{ // If null or is a
// leaf, do nothing
if (root == null || isLeaf(root))
return ;
// Process left and right
// subtrees before this node
sinkevenNodes(root.left);
sinkevenNodes(root.right);
// If root is even, sink it
if (!(root.data & 1))
sink(root);
} // Helper function to do Level // Order Traversal of Binary Tree // level by level. This function // is used here only for showing // modified tree. function printLevelOrder(root)
{ var q = [];
q.push(root);
// Do Level order traversal
while (q.length!=0) {
var nodeCount = q.length;
// Print one level at a time
while (nodeCount) {
var node = q[0];
document.write(node.data + " " );
q.shift();
// If the node has a left
// child then push into queue
if (node.left != null )
q.push(node.left);
// If the node has a right
// child then push into queue
if (node.right != null )
q.push(node.right);
nodeCount--;
}
// Line separator for levels
document.write( "<br>" );
}
} // Driver code /* Constructed binary tree is
1
/ \
5 8
/ \ / \
2 4 9 10 */
var root = newnode(1);
root.left = newnode(5);
root.right = newnode(8);
root.left.left = newnode(2);
root.left.right = newnode(4);
root.right.left = newnode(9);
root.right.right = newnode(10);
// Calling function to perform
// sink operation
sinkevenNodes(root);
// Printing the updated tree
// using level order traversal
printLevelOrder(root);
</script> |
Output:
1 5 9 2 4 8 10