Open In App

Convert Binary Tree to Doubly Linked List using Morris Traversal

Last Updated : 15 Dec, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

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 <=> 2

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

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([]);


Output

Actual order: 40 20 60 10 30 
Reverse Order: 30 10 60 20 40 

Time Complexity: O(N)
Auxiliary Space: O(1)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads