Given the root of a binary tree, flatten the tree into a Linked list using Preorder.
The linked list should use the same Node class where the right child pointer points to the next node in the list and the left child pointer is always null.
The linked list nodes should be in the same order as a preorder traversal of the binary tree.
Examples:
Input: root[] = [1, 2, 5, 3, 4, N, 6]
Output: [1, 2, 3, 4, 5, 6] Explanation: After flattening, the tree looks like: 1 \ 2 \ 3 \ 4 \ 5 \ 6 Here, left of each node points to NULL and right contains the next node in preorder. The inorder traversal of this flattened tree is 1 2 3 4 5 6.
Input: root[] = [1, 3, 4, N, N, 2, N, N, 5]
Output: [1, 3, 4, 2, 5] Explanation: After flattening, the tree looks like: 1 \ 3 \ 4 \ 2 \ 5 Here, left of each node points to NULL and right contains the next node in preorder. The inorder traversal of this flattened tree is 1 3 4 2 5.
[Naive Approach] Preorder + Find Tail - O(n^2) Time and O(h) Space
Flatten the left subtree.
Flatten the right subtree.
Move the flattened left subtree to the right.
Attach the flattened right subtree after it.
C++
#include<bits/stdc++.h>usingnamespacestd;/* Structure of a Binary Tree Node */classNode{public:intdata;Node*left;Node*right;Node(intval){data=val;left=nullptr;right=nullptr;}};// Returns the last node of the flattened subtree.Node*flattenTree(Node*root){// Base caseif(root==nullptr)returnnullptr;// Flatten left and right subtrees.Node*leftTail=flattenTree(root->left);Node*rightTail=flattenTree(root->right);// If left subtree exists, place it between// root and the original right subtree.if(root->left!=nullptr){Node*tempRight=root->right;root->right=root->left;root->left=nullptr;// Attach original right subtree after// the flattened left subtree.leftTail->right=tempRight;}// Return the last node of the flattened subtree.if(rightTail!=nullptr)returnrightTail;if(leftTail!=nullptr)returnleftTail;returnroot;}voidflatten(Node*root){flattenTree(root);}voidprintFlattenedTree(Node*root){while(root!=nullptr){cout<<root->data<<" ";root=root->right;}cout<<endl;}intmain(){/* 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<<"Flattened Binary Tree: ";printFlattenedTree(root);return0;}
Java
importjava.util.LinkedList;importjava.util.Queue;/* Structure of a Binary Tree Node */classNode{publicintdata;publicNodeleft;publicNoderight;publicNode(intval){data=val;left=null;right=null;}}publicclassMain{// Returns the last node of the flattened subtree.privatestaticNodeflattenTree(Noderoot){// Base caseif(root==null)returnnull;// Flatten left and right subtrees.NodeleftTail=flattenTree(root.left);NoderightTail=flattenTree(root.right);// If left subtree exists, place it between// root and the original right subtree.if(root.left!=null){NodetempRight=root.right;root.right=root.left;root.left=null;// Attach original right subtree after// the flattened left subtree.leftTail.right=tempRight;}// Return the last node of the flattened subtree.if(rightTail!=null)returnrightTail;if(leftTail!=null)returnleftTail;returnroot;}publicstaticvoidflatten(Noderoot){flattenTree(root);}publicstaticvoidprintFlattenedTree(Noderoot){while(root!=null){System.out.print(root.data+" ");root=root.right;}System.out.println();}publicstaticvoidmain(String[]args){/* 1 / \ 2 5 / \ \ 3 4 6 */Noderoot=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("Flattened Binary Tree: ");printFlattenedTree(root);}}
Python
classNode:def__init__(self,val):self.data=valself.left=Noneself.right=None# Returns the last node of the flattened subtree.defflattenTree(root):# Base caseifrootisNone:returnNone# Flatten left and right subtrees.leftTail=flattenTree(root.left)rightTail=flattenTree(root.right)# If left subtree exists, place it between# root and the original right subtree.ifroot.leftisnotNone:tempRight=root.rightroot.right=root.leftroot.left=None# Attach original right subtree after# the flattened left subtree.leftTail.right=tempRight# Return the last node of the flattened subtree.ifrightTailisnotNone:returnrightTailifleftTailisnotNone:returnleftTailreturnrootdefflatten(root):flattenTree(root)defprintFlattenedTree(root):whilerootisnotNone:print(root.data,end=' ')root=root.rightprint('')root=Node(1)root.left=Node(2)root.right=Node(5)root.left.left=Node(3)root.left.right=Node(4)root.right.right=Node(6)flatten(root)print('Flattened Binary Tree:')printFlattenedTree(root)
C#
usingSystem;// Structure of a Binary Tree NodepublicclassNode{publicintdata;publicNodeleft;publicNoderight;publicNode(intval){data=val;left=null;right=null;}}publicclassMainClass{// Returns the last node of the flattened subtree.privatestaticNodeflattenTree(Noderoot){// Base caseif(root==null)returnnull;// Flatten left and right subtrees.NodeleftTail=flattenTree(root.left);NoderightTail=flattenTree(root.right);// If left subtree exists, place it between// root and the original right subtree.if(root.left!=null){NodetempRight=root.right;root.right=root.left;root.left=null;// Attach original right subtree after// the flattened left subtree.leftTail.right=tempRight;}// Return the last node of the flattened subtree.if(rightTail!=null)returnrightTail;if(leftTail!=null)returnleftTail;returnroot;}publicstaticvoidflatten(Noderoot){flattenTree(root);}publicstaticvoidprintFlattenedTree(Noderoot){while(root!=null){Console.Write(root.data+" ");root=root.right;}Console.WriteLine();}publicstaticvoidMain(string[]args){/* 1 / \ 2 5 / \ \ 3 4 6 */Noderoot=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("Flattened Binary Tree: ");printFlattenedTree(root);}}
JavaScript
/* Structure of a Binary Tree Node */classNode{constructor(val){this.key=val;this.left=null;this.right=null;}}// Returns the last node of the flattened subtree.functionflattenTree(root){// Base caseif(root===null)returnnull;// Flatten left and right subtrees.letleftTail=flattenTree(root.left);letrightTail=flattenTree(root.right);// If left subtree exists, place it between// root and the original right subtree.if(root.left!==null){lettempRight=root.right;root.right=root.left;root.left=null;// Attach original right subtree after// the flattened left subtree.leftTail.right=tempRight;}// Return the last node of the flattened subtree.if(rightTail!==null)returnrightTail;if(leftTail!==null)returnleftTail;returnroot;}functionflatten(root){flattenTree(root);}functionprintFlattenedTree(root){while(root!==null){console.log(root.key+" ");root=root.right;}console.log("");}letroot=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.log("Flattened Binary Tree:");printFlattenedTree(root);
Output
1 2 3 4 5 6
[Better Approach] Reverse Preorder - O(n) Time and O(h) Space
The idea is to process the tree in reverse preorder: Right -> Left -> Root, so that when we process a node, its next node in the required preorder list is already available in prev.
We then connect root-> right to prev and set root-> left = null, gradually building the flattened list in Root -> Left -> Right order.
If root is null, return the previously processed node prev.
Recursively process the right subtree first and update prev.
Recursively process the left subtree and update prev.
Set root->right = prev and make root->left = null.
Update prev = root and return it.
This reverse preorder processing builds the flattened tree in preorder: Root -> Left -> Right.
C++
#include<bits/stdc++.h>usingnamespacestd;/* Structure of a Binary Tree Node */classNode{public:intdata;Node*left;Node*right;Node(intval){data=val;left=nullptr;right=nullptr;}};Node*flattenTree(Node*root,Node*prev){// Base case: empty treeif(root==nullptr)returnprev;// Process right subtree firstprev=flattenTree(root->right,prev);// Process left subtreeprev=flattenTree(root->left,prev);// Connect current node to previously processed noderoot->right=prev;// Left pointer must always be NULLroot->left=nullptr;// Update prev to current nodeprev=root;returnprev;}voidflatten(Node*root){// Initialize previous node as NULLNode*prev=nullptr;flattenTree(root,prev);}voidprintFlattenedTree(Node*root){while(root!=nullptr){cout<<root->data<<" ";root=root->right;}cout<<endl;}intmain(){/* 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);printFlattenedTree(root);return0;}
Java
/* Structure of a Binary Tree Node */classNode{intdata;Nodeleft;Noderight;Node(intval){data=val;left=null;right=null;}}classGFG{staticNodeflattenTree(Noderoot,Nodeprev){// Base case: empty treeif(root==null)returnprev;// Process right subtree firstprev=flattenTree(root.right,prev);// Process left subtreeprev=flattenTree(root.left,prev);// Connect current node to previously processed noderoot.right=prev;// Left pointer must always be NULLroot.left=null;// Update prev to current nodeprev=root;returnprev;}staticvoidflatten(Noderoot){// Initialize previous node as NULLNodeprev=null;prev=flattenTree(root,prev);}staticvoidprintFlattenedTree(Noderoot){while(root!=null){System.out.print(root.data+" ");root=root.right;}System.out.println();}publicstaticvoidmain(String[]args){/* 1 / \ 2 5 / \ \ 3 4 6 */Noderoot=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);printFlattenedTree(root);}}
Python
# Structure of a Binary Tree NodeclassNode:def__init__(self,val):self.data=valself.left=Noneself.right=NonedefflattenTree(root,prev):# Base case: empty treeifrootisNone:returnprev# Process right subtree firstprev=flattenTree(root.right,prev)# Process left subtreeprev=flattenTree(root.left,prev)# Connect current node to previously processed noderoot.right=prev# Left pointer must always be NULLroot.left=None# Update prev to current nodeprev=rootreturnprevdefflatten(root):# Initialize previous node as NULLprev=NoneflattenTree(root,prev)defprintFlattenedTree(root):whilerootisnotNone:print(root.data,end=" ")root=root.rightprint()# Driver Codeif__name__=="__main__":""" 1 / \ 2 5 / \ \ 3 4 6 """root=Node(1)root.left=Node(2)root.right=Node(5)root.left.left=Node(3)root.left.right=Node(4)root.right.right=Node(6)flatten(root)printFlattenedTree(root)
C#
usingSystem;/* Structure of a Binary Tree Node */classNode{publicintdata;publicNodeleft;publicNoderight;publicNode(intval){data=val;left=null;right=null;}}classGFG{staticNodeflattenTree(Noderoot,Nodeprev){// Base case: empty treeif(root==null)returnprev;// Process right subtree firstprev=flattenTree(root.right,prev);// Process left subtreeprev=flattenTree(root.left,prev);// Connect current node to previously processed noderoot.right=prev;// Left pointer must always be NULLroot.left=null;// Update prev to current nodeprev=root;returnprev;}staticvoidflatten(Noderoot){// Initialize previous node as NULLNodeprev=null;prev=flattenTree(root,prev);}staticvoidprintFlattenedTree(Noderoot){while(root!=null){Console.Write(root.data+" ");root=root.right;}Console.WriteLine();}staticvoidMain(){/* 1 / \ 2 5 / \ \ 3 4 6 */Noderoot=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);printFlattenedTree(root);}}
JavaScript
/* Structure of a Binary Tree Node */classNode{constructor(val){this.data=val;this.left=null;this.right=null;}}functionflattenTree(root,prev){// Base case: empty treeif(root===null)returnprev;// Process right subtree firstprev=flattenTree(root.right,prev);// Process left subtreeprev=flattenTree(root.left,prev);// Connect current node to previously processed noderoot.right=prev;// Left pointer must always be NULLroot.left=null;// Update prev to current nodeprev=root;returnprev;}functionflatten(root){// Initialize previous node as NULLletprev=null;prev=flattenTree(root,prev);}functionprintFlattenedTree(root){letres="";while(root!==null){res+=root.data+" ";root=root.right;}console.log(res.trim());}// Driver Code/* 1 / \ 2 5 / \ \ 3 4 6 */letroot=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);printFlattenedTree(root);
Output
1 2 3 4 5 6
[Expected Approach] Morris Traversal - O(n) Time and O(1) Space
The idea is to use Morris Traversal to flatten the tree in-place without recursion or a stack.
For each node with a left subtree, we connect the original right subtree to the rightmost node of the left subtree, then move the left subtree to the right, maintaining the Root -> Left -> Right preorder order while using O(1) extra space.
Start from the root and process each node while curr != null.
If curr has no left child, simply move to curr->right.
Otherwise, find the rightmost node of curr's left subtree.
Connect this rightmost node to curr->right (the original right subtree).
Move the left subtree to curr->right and set curr->left = null.
Move to curr->right and repeat until the entire tree is flattened.
C++
#include<bits/stdc++.h>usingnamespacestd;/* Structure of a Binary Tree Node */classNode{public:intdata;Node*left;Node*right;Node(intval){data=val;left=nullptr;right=nullptr;}};voidflatten(Node*root){Node*curr=root;while(curr!=nullptr){// If left subtree existsif(curr->left!=nullptr){// Find the rightmost node of the left subtreeNode*predecessor=curr->left;while(predecessor->right!=nullptr)predecessor=predecessor->right;// Attach the original right subtreepredecessor->right=curr->right;// Move the left subtree to the rightcurr->right=curr->left;// Left pointer must always be NULLcurr->left=nullptr;}// Move to the next nodecurr=curr->right;}}voidprintFlattenedTree(Node*root){while(root!=nullptr){cout<<root->data<<" ";root=root->right;}cout<<endl;}intmain(){/* 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);printFlattenedTree(root);return0;}
Java
/* Structure of a Binary Tree Node */classNode{intdata;Nodeleft;Noderight;Node(intval){data=val;left=null;right=null;}}classGFG{staticvoidflatten(Noderoot){Nodecurr=root;while(curr!=null){// If left subtree existsif(curr.left!=null){// Find the rightmost node of the left// subtreeNodepredecessor=curr.left;while(predecessor.right!=null)predecessor=predecessor.right;// Attach the original right subtreepredecessor.right=curr.right;// Move the left subtree to the rightcurr.right=curr.left;// Left pointer must always be NULLcurr.left=null;}// Move to the next nodecurr=curr.right;}}staticvoidprintFlattenedTree(Noderoot){while(root!=null){System.out.print(root.data+" ");root=root.right;}System.out.println();}publicstaticvoidmain(String[]args){/* 1 / \ 2 5 / \ \ 3 4 6 */Noderoot=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);printFlattenedTree(root);}}
Python
# Structure of a Binary Tree NodeclassNode:def__init__(self,val):self.data=valself.left=Noneself.right=Nonedefflatten(root):curr=rootwhilecurrisnotNone:# If left subtree existsifcurr.leftisnotNone:# Find the rightmost node of the left subtreepredecessor=curr.leftwhilepredecessor.rightisnotNone:predecessor=predecessor.right# Attach the original right subtreepredecessor.right=curr.right# Move the left subtree to the rightcurr.right=curr.left# Left pointer must always be NULLcurr.left=None# Move to the next nodecurr=curr.rightdefprintFlattenedTree(root):whilerootisnotNone:print(root.data,end=" ")root=root.rightprint()# Driver Codeif__name__=="__main__":""" 1 / \ 2 5 / \ \ 3 4 6 """root=Node(1)root.left=Node(2)root.right=Node(5)root.left.left=Node(3)root.left.right=Node(4)root.right.right=Node(6)flatten(root)printFlattenedTree(root)
C#
usingSystem;/* Structure of a Binary Tree Node */classNode{publicintdata;publicNodeleft;publicNoderight;publicNode(intval){data=val;left=null;right=null;}}classGFG{staticvoidflatten(Noderoot){Nodecurr=root;while(curr!=null){// If left subtree existsif(curr.left!=null){// Find the rightmost node of the left// subtreeNodepredecessor=curr.left;while(predecessor.right!=null)predecessor=predecessor.right;// Attach the original right subtreepredecessor.right=curr.right;// Move the left subtree to the rightcurr.right=curr.left;// Left pointer must always be NULLcurr.left=null;}// Move to the next nodecurr=curr.right;}}staticvoidprintFlattenedTree(Noderoot){while(root!=null){Console.Write(root.data+" ");root=root.right;}Console.WriteLine();}staticvoidMain(){/* 1 / \ 2 5 / \ \ 3 4 6 */Noderoot=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);printFlattenedTree(root);}}
JavaScript
/* Structure of a Binary Tree Node */classNode{constructor(val){this.data=val;this.left=null;this.right=null;}}functionflatten(root){letcurr=root;while(curr!==null){// If left subtree existsif(curr.left!==null){// Find the rightmost node of the left subtreeletpredecessor=curr.left;while(predecessor.right!==null)predecessor=predecessor.right;// Attach the original right subtreepredecessor.right=curr.right;// Move the left subtree to the rightcurr.right=curr.left;// Left pointer must always be NULLcurr.left=null;}// Move to the next nodecurr=curr.right;}}functionprintFlattenedTree(root){letres="";while(root!==null){res+=root.data+" ";root=root.right;}console.log(res.trim());}// Driver code/* 1 / \ 2 5 / \ \ 3 4 6 */letroot=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);printFlattenedTree(root);