Get free ebooK with 50 must do coding Question for Product Based Companies solved
Fill the details & get ebook over email
Thank You!
We have sent the Ebook on 50 Must Do Coding Questions for Product Based Companies Solved over your email. All the best!

Flatten Binary Tree To Linked List

Last Updated on March 10, 2022 by Ria Pathak

Introduction

The linked list is one of the most important concepts and data structures to learn while preparing for interviews. Having a good grasp of Linked Lists can be a huge plus point in a coding interview.

Problem Statement

Given a binary tree, flatten it into a linked list in place. After flattening, the left of each node should point to NULL, and the right should contain the next node in preorder.

Problem Statement Understanding

In this problem, we are given a binary tree, and we have to flatten it and represent it as a linked list.

Now, you all might be confused with the word flatten, this word simply means that as we know a tree data structure is a non-linear data structure, so what we have to actually do here is to convert this non-linear data structure to a linear data structure (linked list).

Now, let’s try to understand the problem with the help of examples.

Suppose we have a binary tree as:

  • Now, according to the problem statement, if we flatten the given binary tree, the flattened version of this binary tree will be:

  • ![](https://blog.prepbytes.com/wp-content/uploads/2021/10/example-1-output.png)

  • Now, you might wonder how did we get the above-flattened version.

    • The answer is that if you have read the problem statement carefully, it tells us that we need to flatten the binary tree in such a way that the left child of every node is NULL, and the right child contains the next node in preorder, and here in the flattened version, we can clearly see that all the nodes have their left child as NULL and also right child of each node contains the next node in preorder.

Now, taking another example to make it a bit more clear, If our binary tree is:

  • Now, try to draw on your own the flattened representation of the above binary tree.

  • If not able to draw, it’s okay; here we will understand step by step how a binary tree is flattened.

1) We can see that the extreme node to the left in the binary tree is 4, so we will make it as the right of its parent node 2. Also, make sure to preserve the preorder while shifting nodes.

2) Now we will shift all the left child nodes of the parent node 1 to its right following the constraint mentioned in the problem statement, i.e., the left of each node should point to NULL, and the right should contain the next node in preorder.

3) Finally, after the above steps, we will have our flattened binary tree in the form of a singly linked list.

Now, I think from the above examples, the problem statement is clear. Let’s see how we can approach it.

Before moving to the approach section, try to think about how you can approach this problem.

  • If stuck, no problem, we will thoroughly see how we can approach this problem in the next section.

Let’s move to the approach section.

Approach and Algorithm (Brute-Force)

Now, the approach and algorithm for the brute-force approach will be as follows:

  • First, declare a stack named node_stk.
  • Now we will iterate through the loop satisfying the condition that, either root node is not NULL or node_stk is not empty.
  • Now, check if the right child of the current root node is not NULL:
    • If yes then, push the right child in node_stk.
    • After that shift, the left node of the current root node to its right, and point the left child to NULL.
  • Now, if root->right == NULL and also node_stk is not empty:
    • Then, it means that there was no left child of the current root node, so that’s why we have to make root->right point to the original root’s right node, which we pushed into the stack earlier.
    • We will then pop the stack.
  • We will then make root equal to root->right, and the above process will repeat until we flatten our binary tree completely.

Code Implementation

#include 
#include 
using namespace std;
 
struct Node {
    int key;
    Node *left, *right;
};
 
/* utility that allocates a new Node
   with the given key  */
Node* newNode(int key)
{
    Node* node = new Node;
    node->key = key;
    node->left = node->right = NULL;
    return (node);
}
 
// To find the inorder traversal
void inorder(struct Node* root)
{
    // base condition
    if (root == NULL)
        return;
    inorder(root->left);
    cout << root->key << " ";
    inorder(root->right);
}
 
// Function to convert binary tree into
// linked list by altering the right node
// and making left node point to NULL
Node* solution(Node* A)
{
 
    // Declare a stack
    stack st;
    Node* ans = A;
 
    // Iterate till the stack is not empty
    // and till root is Null
    while (A != NULL || st.size() != 0) {
 
        // Check for NULL
        if (A->right != NULL) {
            st.push(A->right);
        }
 
        // Make the Right Left and
        // left NULL
        A->right = A->left;
        A->left = NULL;
 
        // Check for NULL
        if (A->right == NULL && st.size() != 0) {
            A->right = st.top();
            st.pop();
        }
 
        // Iterate
        A = A->right;
    }
    return ans;
}
 
// Driver Code
int main()
{
    /*    1
        /   \
       2     5
      / \     \
     3   4     6 */
 
    // Build the tree
    Node* root = newNode(1);
    root->left = newNode(2);
    root->right = newNode(5);
    root->left->left = newNode(3);
    root->left->right = newNode(4);
    root->right->right = newNode(6);
 
    // Call the function to
    // flatten the tree
    root = solution(root);
 
    cout << "The Inorder traversal after "
            "flattening binary tree ";
 
    // call the function to print
    // inorder after flattening
    inorder(root);
    return 0;
 
    return 0;
}
class Node:
	
	def __init__(self):
		
		self.key = 0
		self.left = None
		self.right = None

# Utility that allocates a new Node
# with the given key
def newNode(key):
	
	node = Node()
	node.key = key
	node.left = node.right = None
	return (node)

# Function to convert binary tree into linked list
def flatten(root):

	node_stk = []
	ans = root
	# Iterate till the stack is not empty and till root is Null
	while (root or len(node_stk)):
		# Check for NULL
		if (root.right):
			node_stk.append(root.right)
		
		# Make the Right node  Left and left  node NULL
		root.right = root.left
		root.left = None
		
		# Check for NULL condition
		if (root.right == None and len(node_stk) != 0):
			root.right = node_stk[-1]
			node_stk.pop()
		
		# Iterate to the right child
		root= root.right
	
	return ans

# To find the inorder traversal
def inorder(root):

	# Base condition
	if (root == None):
		return
	
	inorder(root.left)
	print(root.key, end = ' ')
	inorder(root.right)

# Driver Code
if __name__=='__main__':
	
	root = newNode(1)
	root.left = newNode(2)
	root.right = newNode(3)
	root.left.right = newNode(4)
	root.left.right.right = newNode(5)

	print("The Inorder traversal before flattening binary tree",end=" ")
	inorder(root)
	print()
	flatten(root)

	print("The Inorder traversal after "
		"flattening binary tree ",
		end = '')
	inorder(root)
class Node 
{
	int data;
	Node left, right;
	Node(int key)
	{
		data = key;
		left = right = null;
	}
}
class Flatten 
{

	Node root;
	public void flatten(Node node)
	{
		// Base case - return if root is NULL
		if (node == null)
			return;
		// Or if it is a leaf node
		if (node.left == null && node.right == null)
			return;
		// If root.left children exists then we have to make
		// it node.right (where node is root)
		if (node.left != null) {
			// Move left recursively
			flatten(node.left);
			// Store the node.right in Node named tempNode
			Node tempNode = node.right;
			node.right = node.left;
			node.left = null;
			// Find the position to insert the stored value
			Node curr = node.right;
			while (curr.right != null)
				curr = curr.right;
			// Insert the stored value
			curr.right = tempNode;
		}
		// Now call the same function for node.right
		flatten(node.right);
	}
	public void inOrder(Node node)
	{
		if (node == null)
			return;
		inOrder(node.left);
		System.out.print(node.data + " ");
		inOrder(node.right);
	}
	public static void main(String[] args)
	{
		Flatten tree=new Flatten();
		tree.root = new Node(1);
		tree.root.left = new Node(2);
		tree.root.right = new Node(5);
		tree.root.left.left = new Node(3);
		tree.root.left.right = new Node(4);
		tree.root.right.right = new Node(6);

		System.out.println("The Inorder traversal after flattening binary tree ");
		tree.flatten(tree.root);
		tree.inOrder(tree.root);
	}
}

Output

The Inorder traversal before flattening binary tree 2 4 5 1 3
The Inorder traversal after flattening binary tree 1 2 4 5 3

Time Complexity: O(n)
Space Complexity: O(n)

The above algorithm will work fine, but the main issue is that it takes O(n) extra space. Can we solve the above problem in O(1) extra space?

  • Okay! If you can’t think of an approach, let me give you a hint from the previous solution.
  • In the previous solution, we have used a stack to solve the problem; what if we use a pointer to temporarily store the right node and then keep putting it after left node, if it exists and this process would go on recursively till all the left child nodes are not NULL.

Still confused? Don’t worry, let’s get this recursive approach more clear by discussing it further.

Approach (Pointer Method)

Our approach will be:

  • Since it will be a recursive approach, so we will need a base case that will terminate the function, and our base case will be:
    • If root is NULL or if it is a leaf node, then return.
  • Get a pointer that will point to the right child of the current parent node, and then replace the right child of the parent node with the left child node.
    • Now, once the node is replaced, we will traverse to the rightmost leaf node of the tree and then will attach the last stored right node to the right of rightmost leaf node, because we have to preserve the order of nodes (preorder) which is given to us.
  • And this process will be repeated till all the left child nodes are not NULL.

Now, to get a clear understanding of how this approach works, let’s have a look at its algorithm:

Algorithm (Pointer Method)

1) Base Case: if the root is NULL or the root is a leaf node, we will end the recursive function and return, else we will move on to step 2.
2) Now, we will check if the root has a left child.

  • Yes, if the root has a left child, then store the right child of the root node in a pointer named right_child.
  • After that, shift the left child of the root to the right child and make the left child NULL:
    • root->right = root->left;
    • root->left = NULL;
  • And then, after shifting, we will traverse to the rightmost leaf node, and after reaching it, we will make its right pointer point to the node pointed by right_child.
    3) Now, if there is no left child node, call the function recursively for the right child node and repeat the process.

Dry Run

Code Implementation

#include<stdio.h>
#include<stdlib.h>

struct Node {
    int key;
    struct Node *left;
    struct Node *right;
};
 
/* utility that allocates a new Node
   with the given key  */
struct Node* newNode(int key)
{
    struct Node* node = malloc(sizeof(struct Node*));
    node->key = key;
    node->left = node->right = NULL;
    return (node);
}
 
// Function to convert binary tree into
// linked list by altering the right node
// and making left node point to NULL
void flatten(struct Node* root)
{
    // base condition- return if root is NULL
    // or if it is a leaf node
    if (root == NULL || root->left == NULL &&
                        root->right == NULL) {
        return;
    }
 
    // if root->left exists then we have
    // to make it root->right
    if (root->left != NULL) {
 
        // move left recursively
        flatten(root->left);
    
        // store the node root->right
        struct Node* tmpRight = root->right;
        root->right = root->left;
        root->left = NULL;
 
        // find the position to insert
        // the stored value  
        struct Node* t = root->right;
        while (t->right != NULL) {
            t = t->right;
        }
 
        // insert the stored value
        t->right = tmpRight;
    }
 
    // now call the same function
    // for root->right
    flatten(root->right);
}
 
// To find the inorder traversal
void inorder(struct Node* root)
{
    // base condition
    if (root == NULL)
        return;
    inorder(root->left);
    printf("%d ",root->key);
    inorder(root->right);
}
 
/* Driver program to test above functions*/
int main()
{
    /*    1
        /   \
       2     5
      / \     \
     3   4     6 */
    struct Node* root = newNode(1);
    root->left = newNode(2);
    root->right = newNode(5);
    root->left->left = newNode(3);
    root->left->right = newNode(4);
    root->right->right = newNode(6);
 
    flatten(root);
 
    printf( "The Inorder traversal after "
            "flattening binary tree ");
    inorder(root);
    return 0;
}
#include <bits/stdc++.h>
using namespace std;
 
struct Node {
    int key;
    Node *left, *right;
};
 
// utility that allocates a new Node with the given key
Node* newNode(int key)
{
    Node* node = new Node;
    node->key = key;
    node->left = node->right = NULL;
    return (node);
}
 
// Function to convert binary tree into linked list by
// altering the right node and making left node point to
// NULL
void flatten(struct Node* root)
{
    // base condition- return if root is NULL or if it is a
    // leaf node
    if (root == NULL || root->left == NULL && root->right == NULL)
        return;
    // if root->left exists then we have to make it
    // root->right
    if (root->left != NULL) {
        // move left recursively
        flatten(root->left);
        // store the node root->right
        struct Node* tmpRight = root->right;
        root->right = root->left;
        root->left = NULL;
        // find the position to insert the stored value
        struct Node* t = root->right;
        while (t->right != NULL)
            t = t->right;
        // insert the stored value
        t->right = tmpRight;
    }
    // now call the same function for root->right
    flatten(root->right);
}
 
// To find the inorder traversal
void inorder(struct Node* root)
{
    // base condition
    if (root == NULL)
        return;
    inorder(root->left);
    cout << root->key << " ";
    inorder(root->right);
}
 
/* Driver program to test above functions*/
int main()
{
    /*    1
        /   \
       2     5
      / \     \
     3   4     6 */
    Node* root = newNode(1);
    root->left = newNode(2);
    root->right = newNode(5);
    root->left->left = newNode(3);
    root->left->right = newNode(4);
    root->right->right = newNode(6);
    flatten(root);
    cout << "The Inorder traversal after flattening binary tree ";
    inorder(root);
    return 0;
}
class Node
{
	int data;
	Node left, right;

	Node(int key)
	{
		data = key;
		left = right = null;
	}
}

class Flatten
{
	Node root;
    
    public void flatten(Node node)
    {
	    if (node == null)
		    return;

	    if (node.left == null &&
	        node.right == null)
		    return;

	    if (node.left != null)
	    {
		    flatten(node.left);
		    Node tempNode = node.right;
		    node.right = node.left;
		    node.left = null;

		    Node curr = node.right;
		    while (curr.right != null)
		    {
			    curr = curr.right;
		    }
		    curr.right = tempNode;
	    }
	    flatten(node.right);
    }
    public void inOrder(Node node)
    {
        if (node == null)
		    return;

	    inOrder(node.left);
	    System.out.print(node.data + " ");
	    inOrder(node.right);
    }
    public static void main(String[] args)
    {
	    Flatten tree = new Flatten();

	    tree.root = new Node(1);
	    tree.root.left = new Node(2);
	    tree.root.right = new Node(5);
	    tree.root.left.left = new Node(3);
	    tree.root.left.right = new Node(4);
	    tree.root.right.right = new Node(6);

	    System.out.println("The Inorder traversal after " +"flattening binary tree ");
						
	    tree.flatten(tree.root);
	    tree.inOrder(tree.root);
    }
}

class Node:
	
	def __init__(self):
		
		self.key = 0
		self.left = None
		self.right = None

# Utility that allocates a new Node
# with the given key
def newNode(key):
	
	node = Node()
	node.key = key
	node.left = node.right = None
	return (node)

# Function to convert binary tree into linked list
def flatten(root):

	# Base condition- return if root is None
	# or if it is a leaf node
	if (root == None or root.left == None and
						root.right == None):
		return
	
	# If root.left exists then we have
	# to make it root.right
	if (root.left != None):

		# Move left recursively
		flatten(root.left)
	
		# Store the node root.right
		tmpRight = root.right
		root.right = root.left
		root.left = None

		# Find the position to insert
		# the stored value
		t = root.right
		while (t.right != None):
			t = t.right

		# Insert the stored value
		t.right = tmpRight

	# Now call the same function
	# for root.right
	flatten(root.right)

# To find the inorder traversal
def inorder(root):

	# Base condition
	if (root == None):
		return
	
	inorder(root.left)
	print(root.key, end = ' ')
	inorder(root.right)

# Driver Code
if __name__=='__main__':
	
	root = newNode(1)
	root.left = newNode(2)
	root.right = newNode(3)
	root.left.right = newNode(4)
	root.left.right.right = newNode(5)

	print("The Inorder traversal before flattening binary tree",end=" ")
	inorder(root)
	print()
	flatten(root)

	print("The Inorder traversal after "
		"flattening binary tree ",
		end = '')
	inorder(root)

Output

The Inorder traversal before flattening binary tree 2 4 5 1 3
The Inorder traversal after flattening binary tree 1 2 4 5 3

Time Complexity: The time complexity of this algorithm will be O(n), where n is the number of nodes in the binary tree

[forminator_quiz id=”5484″]

So, in this article, we have tried to explain the most efficient approach to flatten a binary tree to a linked list. This is an important question when it comes to coding interviews. If you want to solve more questions on Linked List, which are curated by our expert mentors at PrepBytes, you can follow this link Linked List.

Leave a Reply

Your email address will not be published. Required fields are marked *