Convert Binary Tree to Doubly Linked List using Morris Traversal
Last Updated :
15 Dec, 2022
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([]);
OutputActual order: 40 20 60 10 30
Reverse Order: 30 10 60 20 40
Time Complexity: O(N)
Auxiliary Space: O(1)