Given a binary tree, flatten it into linked list in-place. Usage of auxiliary data structure is not allowed. After flattening, left of each node should point to NULL and right should contain next node in preorder.
Examples:
Input :
1
/ \
2 5
/ \ \
3 4 6
Output :
1
\
2
\
3
\
4
\
5
\
6
Input :
1
/ \
3 4
/
2
\
5
Output :
1
\
3
\
4
\
2
\
5
Simple Approach: A simple solution is to use Level Order Traversal using Queue. In level order traversal, keep track of previous node. Make current node as right child of previous and left of previous node as NULL. This solution requires queue, but question asks to solve without additional data structure.
Efficient Without Additional Data Structure Recursively look for the node with no grandchildren and both left and right child in the left sub-tree. Then store node->right in temp and make node->right=node->left. Insert temp in first node NULL on right of node by node=node->right. Repeat until it is converted to linked list. Even though this approach does not require additional data structure , but still it takes space for Recursion stack.
For Example,

Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
struct Node {
int key;
Node *left, *right;
};
Node* newNode( int key)
{
Node* node = new Node;
node->key = key;
node->left = node->right = NULL;
return (node);
}
void flatten( struct Node* root)
{
if (root == NULL || root->left == NULL && root->right == NULL)
return ;
if (root->left != NULL) {
flatten(root->left);
struct Node* tmpRight = root->right;
root->right = root->left;
root->left = NULL;
struct Node* t = root->right;
while (t->right != NULL)
t = t->right;
t->right = tmpRight;
}
flatten(root->right);
}
void inorder( struct Node* root)
{
if (root == NULL)
return ;
inorder(root->left);
cout << root->key << " " ;
inorder(root->right);
}
int main()
{
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;
}
|
C
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int key;
struct Node *left, *right;
}Node;
Node* newNode( int key)
{
Node* node = (Node*) malloc ( sizeof (Node));
node->key = key;
node->left = node->right = NULL;
return (node);
}
void flatten(Node* root)
{
if (root == NULL || root->left == NULL && root->right == NULL)
return ;
if (root->left != NULL) {
flatten(root->left);
struct Node* tmpRight = root->right;
root->right = root->left;
root->left = NULL;
struct Node* t = root->right;
while (t->right != NULL)
t = t->right;
t->right = tmpRight;
}
flatten(root->right);
}
void inorder( struct Node* root)
{
if (root == NULL)
return ;
inorder(root->left);
printf ( "%d " , root->key);
inorder(root->right);
}
int main()
{
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;
}
|
Java
class Node {
int data;
Node left, right;
Node( int key)
{
data = key;
left = right = null ;
}
}
class BinaryTree {
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)
{
BinaryTree tree = new BinaryTree();
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);
}
}
|
Python3
class Node:
def __init__( self ):
self .key = 0
self .left = None
self .right = None
def newNode(key):
node = Node()
node.key = key
node.left = node.right = None
return (node)
def flatten(root):
if (root = = None or root.left = = None and
root.right = = None ):
return
if (root.left ! = None ):
flatten(root.left)
tmpRight = root.right
root.right = root.left
root.left = None
t = root.right
while (t.right ! = None ):
t = t.right
t.right = tmpRight
flatten(root.right)
def inorder(root):
if (root = = None ):
return
inorder(root.left)
print (root.key, end = ' ' )
inorder(root.right)
if __name__ = = '__main__' :
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)
print ( "The Inorder traversal after "
"flattening binary tree " ,
end = '')
inorder(root)
|
C#
using System;
class Node
{
public int data;
public Node left, right;
public Node( int key)
{
data = key;
left = right = null ;
}
}
class BinaryTree
{
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);
Console.Write(node.data + " " );
inOrder(node.right);
}
public static void Main( string [] args)
{
BinaryTree tree = new BinaryTree();
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);
Console.Write( "The Inorder traversal after " +
"flattening binary tree " );
tree.flatten(tree.root);
tree.inOrder(tree.root);
}
}
|
Javascript
<script>
class Node
{
constructor(key)
{
this .data = key;
this .left = null ;
this .right = null ;
}
}
var root;
function flatten(node)
{
if (node == null )
return ;
if (node.left == null &&
node.right == null )
return ;
if (node.left != null )
{
flatten(node.left);
var tempNode = node.right;
node.right = node.left;
node.left = null ;
var curr = node.right;
while (curr.right != null )
{
curr = curr.right;
}
curr.right = tempNode;
}
flatten(node.right);
}
function inOrder(node)
{
if (node == null )
return ;
inOrder(node.left);
document.write(node.data + " " );
inOrder(node.right);
}
root = new Node(1);
root.left = new Node(2);
root.right = new Node(5);
root.left.left = new Node(3);
root.left.right = new Node(4);
root.right.right = new Node(6);
document.write( "The Inorder traversal after " +
"flattening binary tree " );
flatten(root);
inOrder(root);
</script>
|
Output
The Inorder traversal after flattening binary tree 1 2 3 4 5 6
Complexity Analysis:
- Time Complexity: O(n), traverse the whole tree
- Space Complexity: O(n), Extra space used for recursion call.
Another Approach:
We will use the intuition behind Morris’s traversal. In Morris Traversal we use the concept of a threaded binary tree.
- At a node(say cur) if there exists a left child, we will find the rightmost node in the left subtree(say prev).
- We will set prev’s right child to cur’s right child,
- We will then set cur’s right child to it’s left child.
- We will then move cur to the next node by assigning cur it to its right child
- We will stop the execution when cur points to NULL.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
struct Node {
int key;
Node *left, *right;
};
Node* newNode( int key)
{
Node* node = new Node;
node->key = key;
node->left = node->right = NULL;
return (node);
}
void flatten(Node* root)
{
while (root) {
if (root->left != NULL) {
Node* curr = root->left;
while (curr->right) {
curr = curr->right;
}
curr->right = root->right;
root->right = root->left;
root->left = NULL;
}
root = root->right;
}
}
void inorder( struct Node* root)
{
if (root == NULL)
return ;
inorder(root->left);
cout << root->key << " " ;
inorder(root->right);
}
int main()
{
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;
}
|
Java
import java.io.*;
class Node {
int key;
Node left, right;
}
class GFG {
static Node newNode( int key)
{
Node node = new Node();
node.key = key;
node.left = node.right = null ;
return node;
}
static void flatten(Node root)
{
while (root != null ) {
if (root.left != null ) {
Node curr = root.left;
while (curr.right != null ) {
curr = curr.right;
}
curr.right = root.right;
root.right = root.left;
root.left = null ;
}
root = root.right;
}
}
static void inorder(Node root)
{
if (root == null ) {
return ;
}
inorder(root.left);
System.out.print(root.key + " " );
inorder(root.right);
}
public static void main(String[] args)
{
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);
System.out.print(
"The Inorder traversal after flattening binary tree " );
inorder(root);
}
}
|
Python3
class Node:
def __init__( self ):
self .key = 0
self .left = None
self .right = None
def newNode(key):
node = Node()
node.key = key
node.left = node.right = None
return (node)
def flatten(root):
while (root ! = None ):
if (root.left ! = None ):
curr = root.left
while (curr.right ! = None ):
curr = curr.right
curr.right = root.right
root.right = root.left
root.left = None
root = root.right
def inorder(root):
if (root = = None ):
return
inorder(root.left)
print (root.key, end = ' ' )
inorder(root.right)
if __name__ = = '__main__' :
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)
print ( "The Inorder traversal after "
"flattening binary tree " ,
end = '')
inorder(root)
|
C#
using System;
class Node
{
public int data;
public Node left, right;
public Node( int key)
{
data = key;
left = right = null ;
}
}
class BinaryTree
{
Node root;
public void flatten(Node node)
{
while (node != null ){
if (node.left != null ){
Node curr = node.left;
while (curr.right != null ){
curr = curr.right;
}
curr.right = node.right;
node.right = node.left;
node.left = null ;
}
node = node.right;
}
}
public void inorder(Node node)
{
if (node == null )
return ;
inorder(node.left);
Console.Write(node.data + " " );
inorder(node.right);
}
public static void Main( string [] args)
{
BinaryTree tree = new BinaryTree();
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);
Console.Write( "The Inorder traversal after " +
"flattening binary tree " );
tree.flatten(tree.root);
tree.inorder(tree.root);
}
}
|
Javascript
<script>
class Node
{
constructor(key)
{
this .data = key;
this .left = null ;
this .right = null ;
}
}
var root;
function flatten(root)
{
while (root){
if (root.left != null ){
curr = root.left;
while (curr.right){
curr = curr.right;
}
curr.right = root.right;
root.right = root.left;
root.left = null ;
}
root = root.right;
}
}
function inorder(root)
{
if (root == null )
return ;
inorder(root.left);
console.log(root.data + " " );
inorder(root.right);
}
root = new Node(1);
root.left = new Node(2);
root.right = new Node(5);
root.left.left = new Node(3);
root.left.right = new Node(4);
root.right.right = new Node(6);
console.log( "The Inorder traversal after " +
"flattening binary tree " );
flatten(root);
inorder(root);
</script>
|
Output
The Inorder traversal after flattening binary tree 1 2 3 4 5 6
Time Complexity: O(N) Time complexity will be the same as that of a Morris’s traversal
Auxiliary Space: O(1)
Another Approach Using Stack:
In this solution, we start by initializing a prev variable to None. This variable will keep track of the previously flattened node as we recursively flatten the binary tree.
- We then define a recursive function flatten that takes in the root node of the binary tree. This function does not return anything, but instead modifies the tree in-place.
- The first thing we do in the flatten function is to check if the root node is None. If it is, we simply return.
- Next, we recursively flatten the right subtree of the root node by calling self.flatten(root.right). This will flatten the right subtree and set self.prev to the rightmost node in the right subtree.
- We then recursively flatten the left subtree of the root node by calling self.flatten(root.left). This will flatten the left subtree and update self.prev to the rightmost node in the flattened left subtree.
- Once we have flattened both the left and right subtrees, we update the root.right pointer to be the previously flattened node (self.prev). We also set the root.left pointer to None to remove the left child.
- Finally, we update self.prev to be the current node (root). This is important because it allows us to keep track of the previously flattened node as we continue to recursively flatten the tree.
This algorithm flattens the binary tree in pre-order traversal, so the resulting “linked list” will be in the same order as a pre-order traversal of the tree.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
struct Node {
int key;
Node *left, *right;
};
Node* newNode( int key)
{
Node* node = new Node;
node->key = key;
node->left = node->right = NULL;
return (node);
}
void flatten(Node* root)
{
stack<Node *>st;
st.push(root);
while (st.empty()!= true )
{
Node *curr = st.top();
st.pop();
if (curr==NULL) return ;
if (curr->right!=NULL) st.push(curr->right);
if (curr->left!=NULL) st.push(curr->left);
if (st.empty()!= true )
{
curr->right = st.top();
}
curr->left = NULL;
}
return ;
}
void inorder( struct Node* root)
{
if (root == NULL)
return ;
inorder(root->left);
cout << root->key << " " ;
inorder(root->right);
}
int main()
{
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;
}
|
C#
using System;
using System.Collections.Generic;
public class Node {
public int key;
public Node left, right;
}
public class FlattenBinaryTreeToLinkedList {
static Node NewNode( int key) {
Node node = new Node();
node.key = key;
node.left = node.right = null ;
return node;
}
static void Flatten(Node root) {
if (root == null ) return ;
Stack<Node> stack = new Stack<Node>();
stack.Push(root);
while (stack.Count != 0) {
Node curr = stack.Pop();
if (curr == null ) continue ;
if (curr.right != null ) stack.Push(curr.right);
if (curr.left != null ) stack.Push(curr.left);
if (stack.Count != 0) {
curr.right = stack.Peek();
}
curr.left = null ;
}
}
static void Inorder(Node root) {
if (root == null ) return ;
Inorder(root.left);
Console.Write(root.key + " " );
Inorder(root.right);
}
public static void Main( string [] args) {
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);
Console.Write( "The Inorder traversal after flattening binary tree " );
Inorder(root);
}
}
|
Output
The Inorder traversal after flattening binary tree 1 2 3 4 5 6
Time Complexity: O(N), The loop will execute for every node once.
Space Complexity: O(N), Auxiliary Stack Space is needed.