Open In App

Convert Binary Tree to Doubly Linked List by keeping track of visited node

Last Updated : 21 Apr, 2024
Summarize
Comments
Improve
Suggest changes
Like Article
Like
Share
Report
News Follow

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 first node of Inorder traversal (leftmost node in BT) must be the head node of the DLL. 

TreeToList

The following two different solutions have been discussed for this problem. 
Convert a given Binary Tree to a Doubly Linked List | Set 1 
Convert a given Binary Tree to a Doubly Linked List | Set 2

Approach: Below is the idea to solve the problem:

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 next to the prev and set previous of this node as prev.

 

Below is the implementation of the above approach:

C++
// A C++ program for in-place conversion of Binary Tree to
// DLL
#include <iostream>
using namespace std;

/* A binary tree node has data, and left and right pointers
 */
struct node {
    int data;
    node* left;
    node* right;
};

// A simple recursive function to convert a given Binary
// tree to Doubly Linked List root --> Root of Binary Tree
// head --> Pointer to head node of created doubly linked
// list
void BinaryTree2DoubleLinkedList(node* root, node** head)
{
    // Base case
    if (root == NULL)
        return;

    // Initialize previously visited node as NULL. This is
    // static so that the same value is accessible in all
    // recursive calls
    static node* prev = NULL;

    // Recursively convert left subtree
    BinaryTree2DoubleLinkedList(root->left, head);

    // Now convert this node
    if (prev == NULL)
        *head = root;
    else {
        root->left = prev;
        prev->right = root;
    }
    prev = root;

    // Finally convert right subtree
    BinaryTree2DoubleLinkedList(root->right, head);
}

/* Helper function that allocates a new node with the
   given data and NULL left and right pointers. */
node* newNode(int data)
{
    node* new_node = new node;
    new_node->data = data;
    new_node->left = new_node->right = NULL;
    return (new_node);
}

/* Function to print nodes in a given doubly linked list */
void printList(node* node)
{
    while (node != NULL) {
        cout << node->data << " ";
        node = node->right;
    }
}

// Driver Code
int main()
{
    // Let us create the tree shown in above diagram
    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);

    // Convert to DLL
    node* head = NULL;
    BinaryTree2DoubleLinkedList(root, &head);

    // Print the converted list
    printList(head);

    return 0;
}

// This code is contributed by Sania Kumari Gupta (kriSania804)
C Java Python3 C# JavaScript

Output
25 12 30 10 36 15 

Note: The use of static variables like above is not a recommended practice, here static is used for simplicity. Imagine if the same function is called for two or more trees. The old value of prev would be used in the next call for a different tree. To avoid such problems, we can use a double-pointer or a reference to a pointer.

Time Complexity: O(N), The above program does a simple inorder traversal, so time complexity is O(N) where N is the number of nodes in a given Binary tree.
Auxiliary Space: O(N), For recursion call stack.

Convert a given Binary Tree to Doubly Linked List iteratively using Stack data structure:

Do iterative inorder traversal and maintain a prev pointer to point the last visited node then point current node’s perv to prev and prev’s next to current node. 

Below is the implementation of the above approach:

C++
// A C++ program for in-place conversion of Binary Tree to
// DLL
#include <bits/stdc++.h>
using namespace std;

/* A binary tree node has data, and left and right pointers
 */
struct node {
    int data;
    node* left;
    node* right;
};

node * bToDLL(node *root)
{
    stack<pair<node*, int>> s;
    s.push({root, 0});
    vector<int> res;
    bool flag = true;
    node* head = NULL;
    node* prev = NULL;
    while(!s.empty()) {
        auto x = s.top();
        node* t = x.first;
        int state = x.second;
        s.pop();
        if(state == 3 or t == NULL) continue;
        s.push({t, state+1});
        if(state == 0) s.push({t->left, 0});
        else if(state == 1) {
            if(prev) prev->right = t;
            t->left = prev;
            prev = t;
            if(flag) {
                head = t;
                flag = false;
            }
        }
        else if(state == 2) s.push({t->right, 0});
    }
    return head;
}

/* Helper function that allocates a new node with the
   given data and NULL left and right pointers. */
node* newNode(int data)
{
    node* new_node = new node;
    new_node->data = data;
    new_node->left = new_node->right = NULL;
    return (new_node);
}

/* Function to print nodes in a given doubly linked list */
void printList(node* node)
{
    while (node != NULL) {
        cout << node->data << " ";
        node = node->right;
    }
}

// Driver Code
int main()
{
    // Let us create the tree shown in above diagram
    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);

    // Convert to DLL
    node* head = bToDLL(root);

    // Print the converted list
    printList(head);

    return 0;
}
Java Python3 C# JavaScript

Output
25 12 30 10 36 15 

Time complexity: O(N)
Auxiliary Space: O(N)

Convert a given Binary Tree to Doubly Linked List iteratively using Morris Traversal:

The idea is to keep track of previous node while doing Inorder tree traversal using Morris Traversal. This removes the need for a recursion call stack or a stack thus reducing space complexity

C++
#include <iostream>

// Structure for a binary tree node
struct Node {
    int data;
    Node* left;
    Node* right;

    // Constructor
    Node(int val) : data(val), left(nullptr), right(nullptr) {}
};

// Function to convert binary tree to doubly linked list
Node* bToDLL(Node* root) {
    // Initialization
    Node* curr = root;
    Node* prev = nullptr; // Used to keep track of prev node
    Node* final_head = nullptr; // Used to return the final head

    // Traverse the tree
    while (curr) {
        // If no left child
        if (!curr->left) {
            // If final_head is not set, set it to current node
            if (!final_head) {
                prev = curr;
                final_head = curr;
            } else {
                // Set next of prev as curr and prev of curr as prev
                prev->right = curr;
                curr->left = prev;
            }
            // Set the new prev node
            prev = curr;
            curr = curr->right;
        } else {
            // If left child exists
            Node* pre = curr->left;
            while (pre->right && pre->right != curr) {
                pre = pre->right;
            }
            if (!pre->right) {
                pre->right = curr;
                curr = curr->left;
            } else {
                curr = pre->right;
                // Set next of prev as curr and prev of curr as prev
                prev->right = curr;
                curr->left = prev;
                // Set the new prev node
                prev = curr;
                curr = curr->right;
            }
        }
    }

    return final_head; // Return the final head of the linked list
}

// Function to print nodes in the doubly linked list
void print_dll(Node* head) {
    while (head != nullptr) {
        std::cout << head->data << " ";
        head = head->right;
    }
}

// Driver code
int main() {
    // Create the binary tree
    Node* 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);

    // Convert the binary tree to doubly linked list
    Node* head = bToDLL(root);

    // Print the converted list
    print_dll(head);

    return 0;
}
Java Python3 JavaScript

Output
25 12 30 10 36 15 

Time complexity: O(N)

Auxiliary Space: O(1)



Next Article

Similar Reads

three90RightbarBannerImg