Last Updated: 28 Jan, 2021

Flatten Binary Tree to Linked List

Moderate
Asked in companies
AppleMicrosoftSalesforce

Problem statement

You are given a binary tree consisting of 'n' nodes.


Convert the given binary tree into a linked list where the linked list nodes follow the same order as the pre-order traversal of the given binary tree.


Use the right pointer of the binary tree as the “next” pointer for the linked list and set the left pointer to NULL.


Use these nodes only. Do not create extra nodes.


Example :
Input: Let the binary be as shown in the figure:

Example Tree

Output: Linked List: 15 -> 40 -> 62 -> 10 -> 20 -> NULL

Explanation: As shown in the figure, the right child of every node points to the next node, while the left node points to null.

Also, the nodes are in the same order as the pre-order traversal of the binary tree.
Input format :
The first line of input contains elements in the level order form for the first binary tree. The line consists of values of nodes separated by a single space. In case a node is null, we take -1 in its place.


Input format explanation:
The level order input for the tree depicted in the below image would be 

alt text

1
2 3
4 -1 5 6
-1 7 -1 -1 -1 -1
-1 -1

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

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).


Output format:
The nodes of the linked list, each separated by a single space, are printed.


Note :
You do not need to print anything; it has already been taken care of. Just implement the given function.

Approaches

01 Approach

  • 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:

 

  1. We start by creating an empty stack and taking the root node as the current node.
  2. 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.
  3. Now, set the right child of the node as the current node.
  4. Repeat the above steps until the current node becomes NULL or the stack becomes empty.

02 Approach

  • 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:

 

  1. Call the recursive function as flattenBinaryTreeHelper(‘head’ , NULL).

 

flattenBinaryTreeHelper('currentNode', 'lastNode'):

 

  1. 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').
  2. We start by calling the function with 'currentNode' as the root of the given subtree and 'lastNode' set to NULL.
  3. Base Condition: If 'currentNode' is NULL, return 'lastNode'.
  4. If 'lastNode' is NOT NULL, then set 'currentNode' as the right child of 'lastNode'.
  5. Store the left and right child of the 'currentNode' in temporary variables, say ‘left’ and ‘right’ respectively.
  6. Set the ‘left’ and ‘right’ pointers of 'currentNode' to NULL.
  7. Recursively call the function as flattenBinaryTreeHelper(‘left’ , 'currentNode'), and store the returned value in a variable, say 'newLastNode'.
  8. Recursively call the function as flattenBinaryTreeHelper(‘right’ , 'newLastNode'), store the returned value in 'newLastNode'.
  9. Finally, return 'newLastNode'.

03 Approach

  • 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: 

 

  1. Let 'currentNode' store the node presently being explored.
  2. We start by exploring the root node. So, initialize 'currentNode' with the root node.
  3. 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.