Convert Binary Tree to Doubly Linked List using Morris Traversal
Given a Binary Tree (BT), convert it to a Doubly Linked List (DLL). The left and right pointers in nodes are to be used as previous and next pointers respectively in converted DLL. The order of nodes in DLL must be the same as in Inorder for the given Binary Tree. The first node of Inorder traversal must be the head node of the DLL.
Examples:
Input:
1
/ \
3 2
Output:
Actual order: 3 1 2
Reverse order: 2 1 3
Explanation: The head of the linked list will be 3 and the last element will be 2.
DLL will be 3 <=> 1 <=> 2Input:
10
/ \
20 30
/ \
40 60
Output:
Actual order: 40 20 60 10 30
Reverse order: 30 10 60 20 40
Below are several approaches that have been discussed earlier:
- Convert a given Binary Tree to a Doubly Linked List | Set 1
- Convert a given Binary Tree to a Doubly Linked List | Set 2
- Convert a given Binary Tree to a Doubly Linked List | Set 3
- Convert a given Binary Tree to a Doubly Linked List | Set 4
Approach:
The above approaches use recursion or stack to get the Inorder Traversal. This approach is based on Morris Traversal to find Inorder Traversal which is iterative and has a space complexity of O(1).
The idea is that we will first create a singly linked list while doing Morris Traversal and later convert it into a doubly-linked list by setting the left pointer of every node to the previous node in inorder.
Follow the steps mentioned below to implement the idea:
- Perform Morris Traversal to traverse the tree in inorder manner in linear time and create the singly linked list.
- Now traverse the singly linked list:
- Create a link in between the current node and the inorder predecessor.
- Update the current and previous (predecessor) node accordingly in each step and move to the next node.
- The doubly linked list generated is the required one.
Below is the implementation of the above approach.
C++
// C++ code to implement the idea #include <bits/stdc++.h> using namespace std; // Structure for tree and linked list struct Node { int data; Node *left, *right; }; // Utility function for allocating node for // Binary Tree. Node* newNode( int data) { Node* node = new Node; node->data = data; node->left = node->right = NULL; return node; } Node* BToDLL(Node* root) { Node* curr = root; // Store head & tail of the linked list // created so far Node *head = NULL, *tail = NULL; // Morris Traversal while (curr) { if (curr->left == NULL) { // If it is to be the first node // of the desired Linked list if (head == NULL) { head = curr; tail = curr; } else { // Append it to the tail of the // linked list we have created // so far & set it as new tail tail->right = curr; tail = tail->right; } curr = curr->right; } else { // Inorder predecessor Node* pred = curr->left; while (pred->right != NULL && pred->right != curr) { pred = pred->right; } if (pred->right == NULL) { pred->right = curr; curr = curr->left; } else { // Append it to the tail of // the linked list // we have created so far & set it // as new tail // Note we don't have to unlink // predecessor tail->right = curr; tail = tail->right; curr = curr->right; } } } curr = head; Node* prev = NULL; // Converting singly linked list to // doubly linked list while (curr) { curr->left = prev; prev = curr; curr = curr->right; } return head; } // Utility function for printing // double linked list. void printList(Node* head) { printf ( "Actual order: " ); while (head) { printf ( "%d " , head->data); head = head->right; } } // Utility function for printing // double linked list in Reverse Order. void printReverseList(Node* tail) { printf ( "\nReverse Order: " ); while (tail) { printf ( "%d " , tail->data); tail = tail->left; } } // Driver code int main() { /* Constructing below tree 10 / \ 20 30 / \ 40 60 */ Node* root = newNode(10); root->left = newNode(20); root->right = newNode(30); root->left->left = newNode(40); root->left->right = newNode(60); // Function call Node* head = BToDLL(root); printList(head); Node* tail = head; // Finding Tail of DLL while (tail && tail->right) { tail = tail->right; } printReverseList(tail); return 0; } |
Java
// Java code to implement the above idea class GFG { // structure of tree and linked list. class Node { int data; Node left, right; } // Utility function for allocating node for binary tree. public Node newNode( int data) { Node node = new Node(); node.data = data; node.left = node.right = null ; return node; } public Node BToDLL(Node root) { Node curr = root; // Store head & tail of the linked list created so // far Node head = null , tail = null ; // Morris Traversal while (curr != null ) { if (curr.left == null ) { // If it is to be the first node of the // desired Linked list. if (head == null ) { head = curr; tail = curr; } else { // Append it to the tail of the linked // list we have created so far & set it // as new tail tail.right = curr; tail = tail.right; } curr = curr.right; } else { // Inorder predecessor Node pred = curr.left; while (pred.right != null && pred.right != curr) { pred = pred.right; } if (pred.right == null ) { pred.right = curr; curr = curr.left; } else { // Append it to the tail of the linked // list we have created so far & set it // as new tail. Note we don't have to // unlink predecessor tail.right = curr; tail = tail.right; curr = curr.right; } } } curr = head; Node prev = null ; // Converting singly linked list to doubly linked // list. while (curr != null ) { curr.left = prev; prev = curr; curr = curr.right; } return head; } // Utility function for printing doubly linked list public void printList(Node head) { System.out.print( "Actual order: " ); while (head != null ) { System.out.print(head.data + " " ); head = head.right; } } // Utility function for printing doubly linked list in // reverse order. public void printReverseList(Node tail) { System.out.print( "\nReverse Order: " ); while (tail != null ) { System.out.print(tail.data + " " ); tail = tail.left; } } public static void main(String[] args) { GFG list = new GFG(); /* Constructing below tree 10 / \ 20 30 / \ 40 60 */ Node root = list.newNode( 10 ); root.left = list.newNode( 20 ); root.right = list.newNode( 30 ); root.left.left = list.newNode( 40 ); root.left.right = list.newNode( 60 ); // Function call Node head = list.BToDLL(root); list.printList(head); Node tail = head; // Finding tail of DLL while (tail != null && tail.right != null ) { tail = tail.right; } list.printReverseList(tail); } } // This code is contributed by lokesh (lokeshmvs21). |
Python
# Python program for above approach class GFG: # structure of tree and linked list. class Node: data = 0 left = None right = None # Utility function for allocating node for binary tree. def newNode( self , data): node = self .Node() node.data = data node.left = node.right = None return node def BToDLL( self , root): curr = root # Store head & tail of the linked list created so # far head = None tail = None # Morris Traversal while curr ! = None : if curr.left = = None : # If it is to be the first node of the # desired Linked list. if head = = None : head = curr tail = curr else : # Append it to the tail of the linked # list we have created so far & set it # as new tail tail.right = curr tail = tail.right curr = curr.right else : # Inorder predecessor pred = curr.left while pred.right ! = None and pred.right ! = curr: pred = pred.right if pred.right = = None : pred.right = curr curr = curr.left else : # Append it to the tail of the linked # list we have created so far & set it # as new tail. Note we don't have to # unlink predecessor tail.right = curr tail = tail.right curr = curr.right curr = head prev = None # Converting singly linked list to doubly linked # list. while curr ! = None : curr.left = prev prev = curr curr = curr.right return head # Utility function for printing doubly linked list def printList( self , head): print ( "Actual order: " ) while head ! = None : print (head.data) head = head.right # Utility function for printing doubly linked list in # reverse order. def printReverseList( self , tail): print ( "\nReverse Order: " ) while tail ! = None : print (tail.data) tail = tail.left # Driver program if __name__ = = '__main__' : list = GFG() # Constructing below tree # 10 # / \ # 20 30 # / \ # 40 60 root = list .newNode( 10 ) root.left = list .newNode( 20 ) root.right = list .newNode( 30 ) root.left.left = list .newNode( 40 ) root.left.right = list .newNode( 60 ) # Function call head = list .BToDLL(root) list .printList(head) tail = head # Finding tail of DLL while tail ! = None and tail.right ! = None : tail = tail.right list .printReverseList(tail) # This code is contributed by adityamaharshi21 |
C#
// C# code to implement the above idea using System; public class GFG { // structure of tree and linked list. public class Node { public int data; public Node left; public Node right; } // Utility function for allocating node for binary tree. public Node newNode( int data) { Node node = new Node(); node.data = data; node.left = node.right = null ; return node; } public Node BToDLL(Node root) { Node curr = root; // Store head & tail of the linked list created so // far Node head = null , tail = null ; // Morris Traversal while (curr != null ) { if (curr.left == null ) { // If it is to be the first node of the // desired Linked list. if (head == null ) { head = curr; tail = curr; } else { // Append it to the tail of the linked // list we have created so far & set it // as new tail tail.right = curr; tail = tail.right; } curr = curr.right; } else { // Inorder predecessor Node pred = curr.left; while (pred.right != null && pred.right != curr) { pred = pred.right; } if (pred.right == null ) { pred.right = curr; curr = curr.left; } else { // Append it to the tail of the linked // list we have created so far & set it // as new tail. Note we don't have to // unlink predecessor tail.right = curr; tail = tail.right; curr = curr.right; } } } curr = head; Node prev = null ; // Converting singly linked list to doubly linked // list. while (curr != null ) { curr.left = prev; prev = curr; curr = curr.right; } return head; } // Utility function for printing doubly linked list public void printList(Node head) { Console.Write( "Actual order: " ); while (head != null ) { Console.Write(head.data + " " ); head = head.right; } } // Utility function for printing doubly linked list in // reverse order. public void printReverseList(Node tail) { Console.Write( "\nReverse Order: " ); while (tail != null ) { Console.Write(tail.data + " " ); tail = tail.left; } } static public void Main() { // Code GFG list = new GFG(); /* Constructing below tree 10 / \ 20 30 / \ 40 60 */ Node root = list.newNode(10); root.left = list.newNode(20); root.right = list.newNode(30); root.left.left = list.newNode(40); root.left.right = list.newNode(60); // Function call Node head = list.BToDLL(root); list.printList(head); Node tail = head; // Finding tail of DLL while (tail != null && tail.right != null ) { tail = tail.right; } list.printReverseList(tail); } } // This code is contributed by lokesh (lokeshmvs21). |
Javascript
// javascript code to implement the above idea class GFG { // structure of tree and linked list. class Node { data = 0; left = null ; right = null ; } // Utility function for allocating node for binary tree. newNode(data) { var node = new this .Node(); node.data = data; node.left = node.right = null ; return node; } BToDLL(root) { var curr = root; // Store head & tail of the linked list created so // far var head = null ; var tail = null ; // Morris Traversal while (curr != null ) { if (curr.left == null ) { // If it is to be the first node of the // desired Linked list. if (head == null ) { head = curr; tail = curr; } else { // Append it to the tail of the linked // list we have created so far & set it // as new tail tail.right = curr; tail = tail.right; } curr = curr.right; } else { // Inorder predecessor var pred = curr.left; while (pred.right != null && pred.right != curr) { pred = pred.right; } if (pred.right == null ) { pred.right = curr; curr = curr.left; } else { // Append it to the tail of the linked // list we have created so far & set it // as new tail. Note we don't have to // unlink predecessor tail.right = curr; tail = tail.right; curr = curr.right; } } } curr = head; var prev = null ; // Converting singly linked list to doubly linked // list. while (curr != null ) { curr.left = prev; prev = curr; curr = curr.right; } return head; } // Utility function for printing doubly linked list printList(head) { console.log( "Actual order: " ); while (head != null ) { console.log(head.data + " " ); head = head.right; } // Utility function for printing doubly linked list in // reverse order. printReverseList(tail) { console.log( "\nReverse Order: " ); while (tail != null ) { console.log(tail.data + " " ); tail = tail.left; } } static main(args) { var list = new GFG(); // Constructing below tree // 10 // / \ // 20 30 // / \ // 40 60 var root = list.newNode(10); root.left = list.newNode(20); root.right = list.newNode(30); root.left.left = list.newNode(40); root.left.right = list.newNode(60); // Function call var head = list.BToDLL(root); list.printList(head); var tail = head; // Finding tail of DLL while (tail != null && tail.right != null ) { tail = tail.right; } list.printReverseList(tail); } } GFG.main([]); |
Actual order: 40 20 60 10 30 Reverse Order: 30 10 60 20 40
Time Complexity: O(N)
Auxiliary Space: O(1)
Please Login to comment...