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)
Similar Reads
Convert Binary Tree to Doubly Linked List using inorder traversal
Given a Binary Tree (BT), the task is to convert it to a Doubly Linked List (DLL) in place. The left and right pointers in nodes will be used as previous and next pointers respectively in converted DLL. The order of nodes in DLL must be the same as the order of the given Binary Tree. The first node
15+ min read
Convert Binary Tree to Doubly Linked List by keeping track of visited node
Given a Binary Tree, The task is to convert it to a Doubly Linked List keeping the same order. 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 fir
15+ min read
Sort the Bitonic Doubly Linked List Using Constant Space
Given a biotonic doubly linked list. The task is to sort the given linked list. A biotonic doubly linked list is a doubly linked list that is first increasing and then decreasing. A strictly increasing or a strictly decreasing list is also a biotonic doubly linked list.Examples:Input: Output: 3 <
15+ min read
Modify a binary tree to get preorder traversal using right pointers only
Given a binary tree. The task is to modify it in such a way that after modification preorder traversal of it can get only with the right pointers. During modification, we can use right as well as left pointers. Examples: Input : Output : Explanation: The preorder traversal of given binary tree is 10
12 min read
Reverse a Doubly linked list using recursion
Given a doubly linked list. Reverse it using recursion. Original Doubly linked list Reversed Doubly linked list We have discussed Iterative solution to reverse a Doubly Linked List Algorithm: If list is empty, return Reverse head by swapping head->prev and head->next If prev = NULL it means th
9 min read
Convert given Binary Tree to Doubly Linked List in Linear time
Given a Binary Tree (BT), the task is to convert it to a Doubly Linked List (DLL) in place. The left and right pointers in nodes will be used as previous and next pointers respectively in converted DLL. The order of nodes in DLL must be the same as the order of the given Binary Tree. The first node
8 min read
Convert a Binary Tree into Doubly Linked List in spiral fashion
Given a binary tree, convert it into a doubly linked list (DLL) where the nodes are arranged in a spiral order. The left pointer of the binary tree node should act as the previous node in the DLL, and the right pointer should act as the next node in the DLL.The solution should not allocate extra mem
10 min read
Convert a Binary Tree to a Circular Doubly Link List
Given a Binary Tree, convert it to a Circular Doubly Linked List (In-Place). The left and right pointers in nodes are to be used as previous and next pointers respectively in the converted Circular Linked List.The order of nodes in the List must be the same as in Inorder for the given Binary Tree.Th
15+ min read
Reverse Morris traversal using Threaded Binary Tree
Given a binary tree, the task is to perform reverse in-order traversal using Morris Traversal.Example:Input:Output: 3 1 5 2 4Explanation: Inorder traversal (Right->Root->Left) of the tree is 3 1 5 2 4Input:Output: 6 5 10 6 8 10 7 1Explanation: Inorder traversal (Right->Root->Left) of the
8 min read
Convert Binary Tree to Doubly Linked List by fixing left and right pointers
Given a Binary Tree, the task is to convert it to a Doubly Linked List (DLL) in place. The left and right pointers in nodes will be used as previous and next pointers respectively in converted DLL. The order of nodes in DLL must be the same as the order of the given Binary Tree. The first node of In
10 min read