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 <=> 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++
#include <bits/stdc++.h>
using namespace std;
struct Node {
int data;
Node *left, *right;
};
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;
Node *head = NULL, *tail = NULL;
while (curr) {
if (curr->left == NULL) {
if (head == NULL) {
head = curr;
tail = curr;
}
else {
tail->right = curr;
tail = tail->right;
}
curr = curr->right;
}
else {
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 {
tail->right = curr;
tail = tail->right;
curr = curr->right;
}
}
}
curr = head;
Node* prev = NULL;
while (curr) {
curr->left = prev;
prev = curr;
curr = curr->right;
}
return head;
}
void printList(Node* head)
{
printf ( "Actual order: " );
while (head) {
printf ( "%d " , head->data);
head = head->right;
}
}
void printReverseList(Node* tail)
{
printf ( "\nReverse Order: " );
while (tail) {
printf ( "%d " , tail->data);
tail = tail->left;
}
}
int main()
{
Node* root = newNode(10);
root->left = newNode(20);
root->right = newNode(30);
root->left->left = newNode(40);
root->left->right = newNode(60);
Node* head = BToDLL(root);
printList(head);
Node* tail = head;
while (tail && tail->right) {
tail = tail->right;
}
printReverseList(tail);
return 0;
}
|
Java
class GFG {
class Node {
int data;
Node left, right;
}
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;
Node head = null , tail = null ;
while (curr != null ) {
if (curr.left == null ) {
if (head == null ) {
head = curr;
tail = curr;
}
else {
tail.right = curr;
tail = tail.right;
}
curr = curr.right;
}
else {
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 {
tail.right = curr;
tail = tail.right;
curr = curr.right;
}
}
}
curr = head;
Node prev = null ;
while (curr != null ) {
curr.left = prev;
prev = curr;
curr = curr.right;
}
return head;
}
public void printList(Node head)
{
System.out.print( "Actual order: " );
while (head != null ) {
System.out.print(head.data + " " );
head = head.right;
}
}
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();
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 );
Node head = list.BToDLL(root);
list.printList(head);
Node tail = head;
while (tail != null && tail.right != null ) {
tail = tail.right;
}
list.printReverseList(tail);
}
}
|
Python
class GFG:
class Node:
data = 0
left = None
right = None
def newNode( self , data):
node = self .Node()
node.data = data
node.left = node.right = None
return node
def BToDLL( self , root):
curr = root
head = None
tail = None
while curr ! = None :
if curr.left = = None :
if head = = None :
head = curr
tail = curr
else :
tail.right = curr
tail = tail.right
curr = curr.right
else :
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 :
tail.right = curr
tail = tail.right
curr = curr.right
curr = head
prev = None
while curr ! = None :
curr.left = prev
prev = curr
curr = curr.right
return head
def printList( self , head):
print ( "Actual order: " )
while head ! = None :
print (head.data)
head = head.right
def printReverseList( self , tail):
print ( "\nReverse Order: " )
while tail ! = None :
print (tail.data)
tail = tail.left
if __name__ = = '__main__' :
list = GFG()
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 )
head = list .BToDLL(root)
list .printList(head)
tail = head
while tail ! = None and tail.right ! = None :
tail = tail.right
list .printReverseList(tail)
|
C#
using System;
public class GFG {
public class Node {
public int data;
public Node left;
public Node right;
}
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;
Node head = null , tail = null ;
while (curr != null ) {
if (curr.left == null ) {
if (head == null ) {
head = curr;
tail = curr;
}
else {
tail.right = curr;
tail = tail.right;
}
curr = curr.right;
}
else {
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 {
tail.right = curr;
tail = tail.right;
curr = curr.right;
}
}
}
curr = head;
Node prev = null ;
while (curr != null ) {
curr.left = prev;
prev = curr;
curr = curr.right;
}
return head;
}
public void printList(Node head)
{
Console.Write( "Actual order: " );
while (head != null ) {
Console.Write(head.data + " " );
head = head.right;
}
}
public void printReverseList(Node tail)
{
Console.Write( "\nReverse Order: " );
while (tail != null ) {
Console.Write(tail.data + " " );
tail = tail.left;
}
}
static public void Main()
{
GFG list = new GFG();
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);
Node head = list.BToDLL(root);
list.printList(head);
Node tail = head;
while (tail != null && tail.right != null ) {
tail = tail.right;
}
list.printReverseList(tail);
}
}
|
Javascript
class GFG
{
class Node
{
data = 0;
left = null ;
right = null ;
}
newNode(data)
{
var node = new this .Node();
node.data = data;
node.left = node.right = null ;
return node;
}
BToDLL(root)
{
var curr = root;
var head = null ;
var tail = null ;
while (curr != null )
{
if (curr.left == null )
{
if (head == null )
{
head = curr;
tail = curr;
}
else
{
tail.right = curr;
tail = tail.right;
}
curr = curr.right;
}
else
{
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
{
tail.right = curr;
tail = tail.right;
curr = curr.right;
}
}
}
curr = head;
var prev = null ;
while (curr != null )
{
curr.left = prev;
prev = curr;
curr = curr.right;
}
return head;
}
printList(head)
{
console.log( "Actual order: " );
while (head != null )
{
console.log(head.data + " " );
head = head.right;
}
printReverseList(tail)
{
console.log( "\nReverse Order: " );
while (tail != null )
{
console.log(tail.data + " " );
tail = tail.left;
}
}
static main(args)
{
var list = new GFG();
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);
var head = list.BToDLL(root);
list.printList(head);
var tail = head;
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)
Last Updated :
15 Dec, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...