Convert a Binary Tree to a Circular Doubly Link List
Last Updated :
10 Jan, 2023
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.
- The first node of Inorder traversal must be the head node of the Circular List.
Examples:
Convert a Binary Tree to a Circular Doubly Link List using Recursion:
The idea is to make a general-purpose function that concatenates two given circular doubly lists
Follow the steps below to solve the problem:
- Recursively convert the left subtree to a circular DLL. Let the converted list be leftList.
- Recursively convert the right subtree to a circular DLL. Let the converted list be rightList.
- Make a circular linked list of roots of the tree, and make the left and right root points to themselves.
- Concatenate leftList with the list of the single root node.
- Concatenate the list produced in the step above with rightList.
Note: The above approach traverses the tree in a Postorder fashion. We can traverse in an inorder fashion also. We can first concatenate left subtree and root, then recur for the right subtree and concatenate the result with left-root concatenation.
How do Concatenate two circular DLLs?
- Get the last node of the left list. Retrieving the last node is an O(1) operation since the prev pointer of the head points to the last node of the list.
- Connect it with the first node of the right list
- Get the last node of the second list
- Connect it with the head of the list.
Below are implementations of the above idea:
C++
#include <iostream>
using namespace std;
struct Node {
struct Node *left, *right;
int data;
};
Node* concatenate(Node* leftList, Node* rightList)
{
if (leftList == NULL)
return rightList;
if (rightList == NULL)
return leftList;
Node* leftLast = leftList->left;
Node* rightLast = rightList->left;
leftLast->right = rightList;
rightList->left = leftLast;
leftList->left = rightLast;
rightLast->right = leftList;
return leftList;
}
Node* bTreeToCList(Node* root)
{
if (root == NULL)
return NULL;
Node* left = bTreeToCList(root->left);
Node* right = bTreeToCList(root->right);
root->left = root->right = root;
return concatenate(concatenate(left, root), right);
}
void displayCList(Node* head)
{
cout << "Circular Linked List is :\n" ;
Node* itr = head;
do {
cout << itr->data << " " ;
itr = itr->right;
} while (head != itr);
cout << "\n" ;
}
Node* newNode( int data)
{
Node* temp = new Node();
temp->data = data;
temp->left = temp->right = NULL;
return temp;
}
int main()
{
Node* root = newNode(10);
root->left = newNode(12);
root->right = newNode(15);
root->left->left = newNode(25);
root->left->right = newNode(30);
root->right->left = newNode(36);
Node* head = bTreeToCList(root);
displayCList(head);
return 0;
}
|
C
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
struct Node *left, *right;
int data;
} Node;
Node* concatenate(Node* leftList, Node* rightList)
{
if (leftList == NULL)
return rightList;
if (rightList == NULL)
return leftList;
Node* leftLast = leftList->left;
Node* rightLast = rightList->left;
leftLast->right = rightList;
rightList->left = leftLast;
leftList->left = rightLast;
rightLast->right = leftList;
return leftList;
}
Node* bTreeToCList(Node* root)
{
if (root == NULL)
return NULL;
Node* left = bTreeToCList(root->left);
Node* right = bTreeToCList(root->right);
root->left = root->right = root;
return concatenate(concatenate(left, root), right);
}
void displayCList(Node* head)
{
printf ( "Circular Linked List is :\n" );
Node* itr = head;
do {
printf ( "%d " , itr->data);
itr = itr->right;
} while (head != itr);
printf ( "\n" );
}
Node* newNode( int data)
{
Node* temp = (Node*) malloc ( sizeof (Node));
temp->data = data;
temp->left = temp->right = NULL;
return temp;
}
int main()
{
Node* root = newNode(10);
root->left = newNode(12);
root->right = newNode(15);
root->left->left = newNode(25);
root->left->right = newNode(30);
root->right->left = newNode(36);
Node* head = bTreeToCList(root);
displayCList(head);
return 0;
}
|
Java
class Node {
int val;
Node left, right;
public Node( int val)
{
this .val = val;
left = right = null ;
}
}
class Tree {
Node root;
public Tree() { root = null ; }
public Node concatenate(Node leftList, Node rightList)
{
if (leftList == null )
return rightList;
if (rightList == null )
return leftList;
Node leftLast = leftList.left;
Node rightLast = rightList.left;
leftLast.right = rightList;
rightList.left = leftLast;
leftList.left = rightLast;
rightLast.right = leftList;
return leftList;
}
public Node bTreeToCList(Node root)
{
if (root == null )
return null ;
Node left = bTreeToCList(root.left);
Node right = bTreeToCList(root.right);
root.left = root.right = root;
return concatenate(concatenate(left, root), right);
}
public void display(Node head)
{
System.out.println( "Circular Linked List is :" );
Node itr = head;
do {
System.out.print(itr.val + " " );
itr = itr.right;
} while (itr != head);
System.out.println();
}
}
class Main {
public static void main(String args[])
{
Tree tree = new Tree();
tree.root = new Node( 10 );
tree.root.left = new Node( 12 );
tree.root.right = new Node( 15 );
tree.root.left.left = new Node( 25 );
tree.root.left.right = new Node( 30 );
tree.root.right.left = new Node( 36 );
Node head = tree.bTreeToCList(tree.root);
tree.display(head);
}
}
|
Python3
class newNode:
def __init__( self , data):
self .data = data
self .left = self .right = None
def concatenate(leftList, rightList):
if (leftList = = None ):
return rightList
if (rightList = = None ):
return leftList
leftLast = leftList.left
rightLast = rightList.left
leftLast.right = rightList
rightList.left = leftLast
leftList.left = rightLast
rightLast.right = leftList
return leftList
def bTreeToCList(root):
if (root = = None ):
return None
left = bTreeToCList(root.left)
right = bTreeToCList(root.right)
root.left = root.right = root
return concatenate(concatenate(left,
root), right)
def displayCList(head):
print ( "Circular Linked List is :" )
itr = head
first = 1
while (head ! = itr or first):
print (itr.data, end = " " )
itr = itr.right
first = 0
print ()
if __name__ = = '__main__' :
root = newNode( 10 )
root.left = newNode( 12 )
root.right = newNode( 15 )
root.left.left = newNode( 25 )
root.left.right = newNode( 30 )
root.right.left = newNode( 36 )
head = bTreeToCList(root)
displayCList(head)
|
C#
using System;
public class Node {
public int val;
public Node left, right;
public Node( int val)
{
this .val = val;
left = right = null ;
}
}
public class Tree {
internal Node root;
public Tree() { root = null ; }
public virtual Node concatenate(Node leftList,
Node rightList)
{
if (leftList == null ) {
return rightList;
}
if (rightList == null ) {
return leftList;
}
Node leftLast = leftList.left;
Node rightLast = rightList.left;
leftLast.right = rightList;
rightList.left = leftLast;
leftList.left = rightLast;
rightLast.right = leftList;
return leftList;
}
public virtual Node bTreeToCList(Node root)
{
if (root == null ) {
return null ;
}
Node left = bTreeToCList(root.left);
Node right = bTreeToCList(root.right);
root.left = root.right = root;
return concatenate(concatenate(left, root), right);
}
public virtual void display(Node head)
{
Console.WriteLine( "Circular Linked List is :" );
Node itr = head;
do {
Console.Write(itr.val + " " );
itr = itr.right;
} while (itr != head);
Console.WriteLine();
}
}
public class GFG {
public static void Main( string [] args)
{
Tree tree = new Tree();
tree.root = new Node(10);
tree.root.left = new Node(12);
tree.root.right = new Node(15);
tree.root.left.left = new Node(25);
tree.root.left.right = new Node(30);
tree.root.right.left = new Node(36);
Node head = tree.bTreeToCList(tree.root);
tree.display(head);
}
}
|
Javascript
<script>
class Node {
constructor(val) {
this .val = val;
this .left = null ;
this .right = null ;
}
}
var root = null ;
function concatenate(leftList, rightList) {
if (leftList == null )
return rightList;
if (rightList == null )
return leftList;
var leftLast = leftList.left;
var rightLast = rightList.left;
leftLast.right = rightList;
rightList.left = leftLast;
leftList.left = rightLast;
rightLast.right = leftList;
return leftList;
}
function bTreeToCList(root) {
if (root == null )
return null ;
var left = bTreeToCList(root.left);
var right = bTreeToCList(root.right);
root.left = root.right = root;
return concatenate(concatenate(left, root), right);
}
function display(head) {
document.write( "Circular Linked List is :<br/>" );
var itr = head;
do {
document.write(itr.val + " " );
itr = itr.right;
} while (itr != head);
document.write();
}
root = new Node(10);
root.left = new Node(12);
root.right = new Node(15);
root.left.left = new Node(25);
root.left.right = new Node(30);
root.right.left = new Node(36);
var head = bTreeToCList(root);
display(head);
</script>
|
Output
Circular Linked List is :
25 12 30 10 36 15
Time Complexity: O(N), As every node is visited at most once.
Auxiliary space: O(log N), The extra space is used in the recursion call stack which can grow up to a maximum size of logN as it is a binary tree.
Convert a Binary Tree to a Circular Doubly Link List by Inorder Traversal:
The idea is to do in-order traversal of the binary tree. While doing inorder traversal, keep track of the previously visited node in a variable, say prev. For every visited node, make it the next of the prev and set previous of this node as prev.
Follow the steps below to solve the problem:
Below is the implementation of the above approach.
C++
#include <iostream>
using namespace std;
struct Node {
int data;
Node* left;
Node* right;
};
Node* BTree2DoublyLinkedList(Node* root, Node** head)
{
if (root == NULL)
return root;
static Node* prev = NULL;
BTree2DoublyLinkedList(root->left, head);
if (prev == NULL)
*head = root;
else {
root->left = prev;
prev->right = root;
}
prev = root;
BTree2DoublyLinkedList(root->right, head);
return prev;
}
Node* BTree2CircularDoublyLinkedList(Node* root)
{
Node* head = NULL;
Node* tail = BTree2DoublyLinkedList(root, &head);
tail->right = head;
head->left = tail;
return head;
}
Node* newNode( int data)
{
Node* new_node = new Node;
new_node->data = data;
new_node->left = new_node->right = NULL;
return (new_node);
}
void printList(Node* head)
{
if (head == NULL)
return ;
Node* ptr = head;
do {
cout << ptr->data << " " ;
ptr = ptr->right;
} while (ptr != head);
}
int main()
{
Node* root = newNode(10);
root->left = newNode(12);
root->right = newNode(15);
root->left->left = newNode(25);
root->left->right = newNode(30);
root->right->left = newNode(36);
Node* head = BTree2CircularDoublyLinkedList(root);
printList(head);
return 0;
}
|
Java
class Node {
int data;
Node left, right;
public Node( int data)
{
this .data = data;
left = right = null ;
}
}
class BinaryTree {
Node root;
Node head;
static Node prev = null ;
void BTree2DoublyLinkedList(Node root)
{
if (root == null )
return ;
BTree2DoublyLinkedList(root.left);
if (prev == null )
head = root;
else {
root.left = prev;
prev.right = root;
}
prev = root;
BTree2DoublyLinkedList(root.right);
}
void BTree2CircularDoublyLinkedList(Node root)
{
BTree2DoublyLinkedList(root);
prev.right = head;
head.left = prev;
}
void printList(Node node)
{
if (node == null )
return ;
Node curr = node;
do {
System.out.print(curr.data + " " );
curr = curr.right;
} while (curr != node);
}
public static void main(String[] args)
{
BinaryTree tree = new BinaryTree();
tree.root = new Node( 10 );
tree.root.left = new Node( 12 );
tree.root.right = new Node( 15 );
tree.root.left.left = new Node( 25 );
tree.root.left.right = new Node( 30 );
tree.root.right.left = new Node( 36 );
tree.BTree2CircularDoublyLinkedList(tree.root);
tree.printList(tree.head);
}
}
|
Python
class Node:
def __init__( self , val):
self .data = val
self .left = None
self .right = None
head = None
prev = None
def BinaryTree2DoubleLinkedList(root):
if (root = = None ):
return
BinaryTree2DoubleLinkedList(root.left)
global prev, head
if (prev = = None ):
head = root
else :
root.left = prev
prev.right = root
prev = root
BinaryTree2DoubleLinkedList(root.right)
def printList(node):
while (node ! = None ):
print (node.data)
node = node.right
root = Node( 10 )
root.left = Node( 12 )
root.right = Node( 15 )
root.left.left = Node( 25 )
root.left.right = Node( 30 )
root.right.left = Node( 36 )
BinaryTree2DoubleLinkedList(root)
printList(head)
|
C#
using System;
public class Node {
public int data;
public Node left, right;
public Node( int data)
{
this .data = data;
left = right = null ;
}
}
public class BinaryTree {
Node root;
Node head;
static Node prev = null ;
void BTree2DoublyLinkedList(Node root)
{
if (root == null )
return ;
BTree2DoublyLinkedList(root.left);
if (prev == null )
head = root;
else {
root.left = prev;
prev.right = root;
}
prev = root;
BTree2DoublyLinkedList(root.right);
}
void BTree2CircularDoublyLinkedList(Node root)
{
BTree2DoublyLinkedList(root);
prev.right = head;
head.left = prev;
}
void printList(Node node)
{
if (node == null )
return ;
Node curr = node;
do {
Console.Write(curr.data + " " );
curr = curr.right;
} while (curr != node);
}
static public void Main()
{
BinaryTree tree = new BinaryTree();
tree.root = new Node(10);
tree.root.left = new Node(12);
tree.root.right = new Node(15);
tree.root.left.left = new Node(25);
tree.root.left.right = new Node(30);
tree.root.right.left = new Node(36);
tree.BTree2CircularDoublyLinkedList(tree.root);
tree.printList(tree.head);
}
}
|
Javascript
class Node {
constructor(val) {
this .data = val;
this .left = null ;
this .right = null ;
}
}
var root;
var head;
var prev = null ;
function BinaryTree2DoubleLinkedList(root)
{
if (root == null )
return ;
BinaryTree2DoubleLinkedList(root.left);
if (prev == null )
head = root;
else {
root.left = prev;
prev.right = root;
}
prev = root;
BinaryTree2DoubleLinkedList(root.right);
}
function printList(node) {
while (node != null ) {
console.log(node.data + " " );
node = node.right;
}
}
root = new Node(10);
root.left = new Node(12);
root.right = new Node(15);
root.left.left = new Node(25);
root.left.right = new Node(30);
root.right.left = new Node(36);
BinaryTree2DoubleLinkedList(root);
printList(head);
|
Time Complexity: O(N), As every node is visited at most once.
Auxiliary space: O(log N), The extra space is used in the recursive function call stack which can grow upto a maximum size of logN.
This approach was contributed by Abhijeet Kumar
Please Login to comment...