Flatten Binary Tree to Linked List
Posted: 28 Jan, 2021
Difficulty: Moderate
You are given a binary tree consisting of integer values. Your task is to convert the given binary tree into a linked list where the nodes of the linked list follow the same order as the pre-order traversal of the given binary tree.
Note:
Use the right pointer of the binary tree as the “next” pointer for the linked list and set the left pointer to NULL.
Follow up:
Can you solve it using constant extra space?
Example:
Consider the binary tree rooted at 15, as shown above (left). On flattening the tree into a linked list we get the resulting tree, as shown above (right). Note that the linked list follows the same order as the pre-order traversal of the given binary tree.
Input format:
The first line of input contains an integer 'T' denoting the number of queries or test cases.
The first and the only line of every test case contains elements of the binary tree in the level order form. The line consists of values of nodes separated by a single space. In case a node is null, we take -1 on its place.
For example:
The input for the tree depicted in the below image would be:
1
2 3
4 -1 5 6
-1 7 -1 -1 -1 -1
-1 -1
Explanation :
Level 1 :
The root node of the tree is 1
Level 2 :
Left child of 1 = 2
Right child of 1 = 3
Level 3 :
Left child of 2 = 4
Right child of 2 = null (-1)
Left child of 3 = 5
Right child of 3 = 6
Level 4 :
Left child of 4 = null (-1)
Right child of 4 = 7
Left child of 5 = null (-1)
Right child of 5 = null (-1)
Left child of 6 = null (-1)
Right child of 6 = null (-1)
Level 5 :
Left child of 7 = null (-1)
Right child of 7 = null (-1)
The first not-null node(of the previous level) is treated as the parent of the first two nodes of the current level. The second not-null node (of the previous level) is treated as the parent node for the next two nodes of the current level and so on.
The input ends when all nodes at the last level are null(-1).
Note :
The above format was just to provide clarity on how the input is formed for a given tree.
The sequence will be put together in a single line separated by a single space. Hence, for the above-depicted tree, the input will be given as:
1 2 3 4 -1 5 6 -1 7 -1 -1 -1 -1 -1 -1
Output format:
For each test case, the nodes of the linked list, each separated by a single space, are printed.
Output for each test case is printed on a separate line.
Note:
You do not need to print anything, it has already been taken care of. Just return the head of the linked list.
Constraints:
1 <= T <= 100
1 <= No. of Nodes <= 5 * 10^4
1 <= data <= 10^5, data!=-1
Where 'data' is the integer data stored in a 'TreeNode' pointer.
Time limit: 1 sec
Approach 1
Approach 2
- A simple approach to solve this problem is by using a stack.
- The idea is to implement the pre-order traversal of the tree using a stack.
Below is the detailed algorithm:
- We start by creating an empty stack and taking the root node as the current node.
- During the exploration of the current node, we check:
- If the current node has the right child, then we push it to the stack.
- If the current node has a left child, then make the left child the new right child of the node and set the left pointer to NULL.
- This is done because the left child is the pre-order successor of the current node hence it must appear just after the current node in the linked list.
- And since we are using the right pointer of the tree as the next pointer for the linked list. Hence, we set the right pointer to the left child.
- Otherwise, if the stack is not empty, we have found the pre-order predecessor of the node present at the top of the stack.
- So, pop the top node from the stack and make it the right child of the current node.
- Now, set the right child of the node as the current node.
- Repeat the above steps until the current node becomes NULL or the stack becomes empty.
- Return the head of the linked list.
Approach 3
- Instead of explicitly creating a stack, a better approach could be to use recursion.
- The idea is to flatten the tree while traversing the tree in a preorder fashion, recursively.
- During the traversal, we keep track of the last node in the flattened linked list. This is done so that the current node can be set as the right child of the last node.
- If the current node is a left child, then its parent node will be the last/previous node in the flattened linked list, as the left child is the pre-order successor of its parent node.
- If the current node is a right child, then there are two possibilities:
- If there is no left child of its parent, then the parent node will be the last/previous node in the linked list.
- Otherwise, the last node in the linked list of the left subtree (i.e. the pre-order predecessor of the current node) will be the last node for the current node.
- In this way, we keep making the current node the right child of the last node. Eventually flattening the complete tree.
Below is the detailed algorithm:
- Store the ‘ROOT’ into a new ‘TREENODE’ pointer named ‘HEAD’.
- Call the recursive function as flattenBinaryTreeHelper(‘ROOT’ , NULL).
- Finally, return 'HEAD'.
flattenBinaryTreeHelper('CURRENTNODE', 'LASTNODE'):
- Let our recursive function be flattenBinaryTreeHelper('CURRENTNODE', 'LASTNODE'), which takes the current node and the last node of the linked list (which has been flattened so far) as its argument and returns the last node of the new flattened linked list (which includes the subtree rooted at 'CURRENTNODE').
- We start by calling the function with 'CURRENTNODE' as the root of the given subtree and 'LASTNODE' set to NULL.
- Base Condition: If 'CURRENTNODE' is NULL, then return 'LASTNODE'.
- If 'LASTNODE' is NOT NULL, then set 'CURRENTNODE' as the right child of 'LASTNODE'.
- Store the left and right child of the 'CURRENTNODE' in temporary variables, say ‘LEFT’ and ‘RIGHT’ respectively.
- Set the ‘LEFT’ and ‘RIGHT’ pointers of 'CURRENTNODE' to NULL.
- Recursively call the function as flattenBinaryTreeHelper(‘LEFT’ , 'CURRENTNODE'), store the returned value in a variable say 'NEW_LAST_NODE'.
- Recursively call the function as flattenBinaryTreeHelper(‘RIGHT’ , 'NEW_LAST_NODE'), store the returned value in 'NEW_LAST_NODE'.
- Finally, return 'NEW_LAST_NODE'.
Approach 4
- This approach is similar to the previous recursive approach.
- The idea is to iteratively traverse the tree.
- While exploring the current node we place its right subtree (of the current node) at the correct position in the tree (i.e. make it the right child of the rightmost node in the left subtree, pre-order predecessor) and make the left subtree the new right subtree of the current node.
- This way we can also avoid keeping track of the last node of the linked list.
Below is the detailed algorithm:
- Let 'CURRENTNODE' store the node presently being explored.
- We start by exploring the root node. So, initialize 'CURRENTNODE' with the root node.
- Repeat the following steps until 'CURRENTNODE' becomes NULL:
- If the current node has a left child:
- Find the rightmost node present in the left subtree and make the right subtree of the current node as its right child.
- Make the left subtree of the current node as the new right subtree.
- Set the left child of the current node is NULL.
- Set 'CURRENTNODE' to 'CURRENTNODE'’s right child.
- If the current node has a left child:
- Return the head of the linked list.
SIMILAR PROBLEMS
Insertion In Circular Linked List
Posted: 21 Apr, 2022
Difficulty: Easy
Height of Binary Tree
Posted: 22 Apr, 2022
Difficulty: Easy
Insertion In A Singly Linked List
Posted: 22 Apr, 2022
Difficulty: Easy
Deletion In Doubly Linked List
Posted: 22 Apr, 2022
Difficulty: Easy
Insertion In Doubly Linked List
Posted: 24 Apr, 2022
Difficulty: Easy