Flattening a Linked List

17 Jun, 2022
Given a linked list where every node represents a linked list and contains two pointers of its type: 
Pointer to next node in the main list (we call it ‘right’ pointer in the code below) Pointer to a linked list where this node is headed (we call it the ‘down’ pointer in the code below). 
Pointer to next node in the main list (we call it ‘right’ pointer in the code below) 
Pointer to a linked list where this node is headed (we call it the ‘down’ pointer in the code below). 
All linked lists are sorted. See the following example  
       5 -> 10 -> 19 -> 28
       |    |     |     |
       V    V     V     V
       7    20    22    35
       |          |     |
       V          V     V
       8          50    40
       |                |
       V                V
       30               45
Write a function flatten() to flatten the lists into a single linked list. The flattened linked list should also be sorted. For example, for the above input list, output list should be 5->7->8->10->19->20->22->28->30->35->40->45->50. 
The idea is to use the Merge() process of merge sort for linked lists. We use merge() to merge lists one by one. We recursively merge() the current list with the already flattened list. The down pointer is used to link nodes of the flattened list.
Below is the implementation of the above approach:
C++
Java
Python3
C#
Javascript
// C++ program for flattening a Linked List#include <bits/stdc++.h>using namespace std; // Link list nodeclass Node{    public:        int data;        Node *right, *down;}; Node* head = NULL; // An utility function to merge two sorted// linked listsNode* merge(Node* a, Node* b){         // If first linked list is empty then second    // is the answer    if (a == NULL)        return b;     // If second linked list is empty then first    // is the result    if (b == NULL)        return a;     // Compare the data members of the two linked    // lists and put the larger one in the result    Node* result;     if (a->data < b->data)    {        result = a;        result->down = merge(a->down, b);    }     else    {        result = b;        result->down = merge(a, b->down);    }    result->right = NULL;    return result;} Node* flatten(Node* root){         // Base Cases    if (root == NULL || root->right == NULL)        return root;     // Recur for list on right    root->right = flatten(root->right);     // Now merge    root = merge(root, root->right);     // Return the root    // it will be in turn merged with its left    return root;} // Utility function to insert a node at// beginning of the linked listNode* push(Node* head_ref, int data){         // Allocate the Node & Put in the data    Node* new_node = new Node();     new_node->data = data;    new_node->right = NULL;     // Make next of new Node as head    new_node->down = head_ref;     // Move the head to point to new Node    head_ref = new_node;     return head_ref;} void printList(){    Node* temp = head;    while (temp != NULL)    {        cout << temp->data << " ";        temp = temp->down;    }    cout << endl;} // Driver codeint main(){         /* Let us create the following linked list        5 -> 10 -> 19 -> 28        |    |     |     |        V    V     V     V        7    20    22    35        |          |     |        V          V     V        8          50    40        |                |        V                V        30               45    */    head = push(head, 30);    head = push(head, 8);    head = push(head, 7);    head = push(head, 5);     head->right = push(head->right, 20);    head->right = push(head->right, 10);     head->right->right = push(head->right->right, 50);    head->right->right = push(head->right->right, 22);    head->right->right = push(head->right->right, 19);     head->right->right->right = push(head->right->right->right, 45);    head->right->right->right = push(head->right->right->right, 40);    head->right->right->right = push(head->right->right->right, 35);    head->right->right->right = push(head->right->right->right, 20);     // Flatten the list    head = flatten(head);     printList();    return 0;} // This code is contributed by rajsanghavi9.
// Java program for flattening a Linked Listclass LinkedList{    Node head;  // head of list     /* Linked list Node*/    class Node    {        int data;        Node right, down;        Node(int data)        {            this.data = data;            right = null;            down = null;        }    }     // An utility function to merge two sorted linked lists    Node merge(Node a, Node b)    {        // if first linked list is empty then second        // is the answer        if (a == null)     return b;         // if second linked list is empty then first        // is the result        if (b == null)      return a;         // compare the data members of the two linked lists        // and put the larger one in the result        Node result;         if (a.data < b.data)        {            result = a;            result.down =  merge(a.down, b);        }         else        {            result = b;            result.down = merge(a, b.down);        }         result.right = null;        return result;    }     Node flatten(Node root)    {        // Base Cases        if (root == null || root.right == null)            return root;         // recur for list on right        root.right = flatten(root.right);         // now merge        root = merge(root, root.right);         // return the root        // it will be in turn merged with its left        return root;    }     /* Utility function to insert a node at beginning of the       linked list */    Node push(Node head_ref, int data)    {        /* 1 & 2: Allocate the Node &                  Put in the data*/        Node new_node = new Node(data);         /* 3. Make next of new Node as head */        new_node.down = head_ref;         /* 4. Move the head to point to new Node */        head_ref = new_node;         /*5. return to link it back */        return head_ref;    }     void printList()    {        Node temp = head;        while (temp != null)        {            System.out.print(temp.data + " ");            temp = temp.down;        }        System.out.println();    }     /* Driver program to test above functions */    public static void main(String args[])    {        LinkedList L = new LinkedList();         /* Let us create the following linked list            5 -> 10 -> 19 -> 28            |    |     |     |            V    V     V     V            7    20    22    35            |          |     |            V          V     V            8          50    40            |                |            V                V            30               45        */         L.head = L.push(L.head, 30);        L.head = L.push(L.head, 8);        L.head = L.push(L.head, 7);        L.head = L.push(L.head, 5);         L.head.right = L.push(L.head.right, 20);        L.head.right = L.push(L.head.right, 10);         L.head.right.right = L.push(L.head.right.right, 50);        L.head.right.right = L.push(L.head.right.right, 22);        L.head.right.right = L.push(L.head.right.right, 19);         L.head.right.right.right = L.push(L.head.right.right.right, 45);        L.head.right.right.right = L.push(L.head.right.right.right, 40);        L.head.right.right.right = L.push(L.head.right.right.right, 35);        L.head.right.right.right = L.push(L.head.right.right.right, 20);         // flatten the list        L.head = L.flatten(L.head);         L.printList();    }} /* This code is contributed by Rajat Mishra */
# Python program for flattening a Linked List class Node():    def __init__(self,data):        self.data = data        self.right = None        self.down = None class LinkedList():    def __init__(self):         # head of list        self.head = None     # Utility function to insert a node at beginning of the    #   linked list    def push(self,head_ref,data):         # 1 & 2: Allocate the Node &        # Put in the data        new_node = Node(data)         # Make next of new Node as head        new_node.down = head_ref         # 4. Move the head to point to new Node        head_ref = new_node         # 5. return to link it back        return head_ref     def printList(self):         temp = self.head        while(temp != None):            print(temp.data,end=" ")            temp = temp.down         print()     # An utility function to merge two sorted linked lists    def merge(self, a, b):        # if first linked list is empty then second        # is the answer        if(a == None):            return b                 # if second linked list is empty then first        # is the result        if(b == None):            return a         # compare the data members of the two linked lists        # and put the larger one in the result        result = None         if (a.data < b.data):            result = a            result.down = self.merge(a.down,b)        else:            result = b            result.down = self.merge(a,b.down)         result.right = None        return result     def flatten(self, root):         # Base Case        if(root == None or root.right == None):            return root        # recur for list on right         root.right = self.flatten(root.right)         # now merge        root = self.merge(root, root.right)         # return the root        # it will be in turn merged with its left        return root # Driver program to test above functionsL = LinkedList() '''Let us create the following linked list            5 -> 10 -> 19 -> 28            |    |     |     |            V    V     V     V            7    20    22    35            |          |     |            V          V     V            8          50    40            |                |            V                V            30               45'''L.head = L.push(L.head, 30);L.head = L.push(L.head, 8);L.head = L.push(L.head, 7);L.head = L.push(L.head, 5); L.head.right = L.push(L.head.right, 20);L.head.right = L.push(L.head.right, 10); L.head.right.right = L.push(L.head.right.right, 50);L.head.right.right = L.push(L.head.right.right, 22);L.head.right.right = L.push(L.head.right.right, 19); L.head.right.right.right = L.push(L.head.right.right.right, 45);L.head.right.right.right = L.push(L.head.right.right.right, 40);L.head.right.right.right = L.push(L.head.right.right.right, 35);L.head.right.right.right = L.push(L.head.right.right.right, 20); # flatten the listL.head = L.flatten(L.head); L.printList()# This code is contributed by maheshwaripiyush9
// C# program for flattening a Linked Listusing System;public class List {    Node head; // head of list     /* Linked list Node */    public   class Node {        public   int data;        public   Node right, down;         public   Node(int data) {            this.data = data;            right = null;            down = null;        }    }     // An utility function to merge two sorted linked lists    Node merge(Node a, Node b) {        // if first linked list is empty then second        // is the answer        if (a == null)            return b;         // if second linked list is empty then first        // is the result        if (b == null)            return a;         // compare the data members of the two linked lists        // and put the larger one in the result        Node result;         if (a.data < b.data) {            result = a;            result.down = merge(a.down, b);        }         else {            result = b;            result.down = merge(a, b.down);        }         result.right = null;        return result;    }     Node flatten(Node root) {        // Base Cases        if (root == null || root.right == null)            return root;         // recur for list on right        root.right = flatten(root.right);         // now merge        root = merge(root, root.right);         // return the root        // it will be in turn merged with its left        return root;    }     /*     * Utility function to insert a node at beginning of the linked list     */    Node Push(Node head_ref, int data) {        /*         * 1 & 2: Allocate the Node & Put in the data         */        Node new_node = new Node(data);         /* 3. Make next of new Node as head */        new_node.down = head_ref;         /* 4. Move the head to point to new Node */        head_ref = new_node;         /* 5. return to link it back */        return head_ref;    }     void printList() {        Node temp = head;        while (temp != null) {            Console.Write(temp.data + " ");            temp = temp.down;        }        Console.WriteLine();    }     /* Driver program to test above functions */    public static void Main(String []args) {        List L = new List();         /*         * Let us create the following linked list 5 -> 10 -> 19 -> 28 | | | | V V V V 7         * 20 22 35 | | | V V V 8 50 40 | | V V 30 45         */         L.head = L.Push(L.head, 30);        L.head = L.Push(L.head, 8);        L.head = L.Push(L.head, 7);        L.head = L.Push(L.head, 5);         L.head.right = L.Push(L.head.right, 20);        L.head.right = L.Push(L.head.right, 10);         L.head.right.right = L.Push(L.head.right.right, 50);        L.head.right.right = L.Push(L.head.right.right, 22);        L.head.right.right = L.Push(L.head.right.right, 19);         L.head.right.right.right = L.Push(L.head.right.right.right, 45);        L.head.right.right.right = L.Push(L.head.right.right.right, 40);        L.head.right.right.right = L.Push(L.head.right.right.right, 35);        L.head.right.right.right = L.Push(L.head.right.right.right, 20);         // flatten the list        L.head = L.flatten(L.head);         L.printList();    }} // This code is contributed by umadevi9616
<script>// javascript program for flattening a Linked Listvar head; // head of list     /* Linked list Node */           class Node {            constructor(val) {                this.data = val;                this.down = null;                this.next = null;            }        }     // An utility function to merge two sorted linked lists    function merge(a,  b) {        // if first linked list is empty then second        // is the answer        if (a == null)            return b;         // if second linked list is empty then first        // is the result        if (b == null)            return a;         // compare the data members of the two linked lists        // and put the larger one in the result        var result;         if (a.data < b.data) {            result = a;            result.down = merge(a.down, b);        }         else {            result = b;            result.down = merge(a, b.down);        }         result.right = null;        return result;    }     function flatten(root) {        // Base Cases        if (root == null || root.right == null)            return root;         // recur for list on right        root.right = flatten(root.right);         // now merge        root = merge(root, root.right);         // return the root        // it will be in turn merged with its left        return root;    }     /*     * Utility function to insert a node at beginning of the linked list     */    function push(head_ref , data) {        /*         * 1 & 2: Allocate the Node & Put in the data         */         var new_node = new Node(data);         /* 3. Make next of new Node as head */        new_node.down = head_ref;         /* 4. Move the head to point to new Node */        head_ref = new_node;         /* 5. return to link it back */        return head_ref;    }     function printList() {    var temp = head;        while (temp != null) {            document.write(temp.data + " ");            temp = temp.down;        }        document.write();    }     /* Driver program to test above functions */                       /*         * Let us create the following linked list 5 -> 10 -> 19 -> 28 | | | | V V V V 7         * 20 22 35 | | | V V V 8 50 40 | | V V 30 45         */         head = push(head, 30);        head = push(head, 8);        head = push(head, 7);        head = push(head, 5);         head.right = push(head.right, 20);        head.right = push(head.right, 10);         head.right.right = push(head.right.right, 50);        head.right.right = push(head.right.right, 22);        head.right.right = push(head.right.right, 19);         head.right.right.right = push(head.right.right.right, 45);        head.right.right.right = push(head.right.right.right, 40);        head.right.right.right = push(head.right.right.right, 35);        head.right.right.right = push(head.right.right.right, 20);         // flatten the list        head = flatten(head);         printList(); // This code contributed by aashish1995</script>
5 7 8 10 19 20 20 22 30 35 40 45 50 
Time Complexity: O(N*N*M) – where N is the no of nodes in main linked list (reachable using right pointer) and M is the no of node in a single sub linked list (reachable using down pointer). 
Explanation: As we are merging 2 lists at a time,
After adding first 2 lists, time taken will be O(M+M) = O(2M).
Then we will merge another list to above merged list -> time = O(2M + M) = O(3M).
Then we will merge another list -> time = O(3M + M).
We will keep merging lists to previously merged lists until all lists are merged.
Total time taken will be O(2M + 3M + 4M + .... N*M) = (2 + 3 + 4 + ... + N)*M
Using arithmetic sum formula: time = O((N*N + N – 2)*M/2)
Above expression is roughly equal to O(N*N*M) for large value of N
Space Complexity: O(N*M) – because of the recursion. The recursive functions will use recursive stack of size equivalent to total number of elements in the lists, which is N*M.
The idea is, to build min-heap and  use Extract-min property  to get minimum element from priority queue.
C++
#include <bits/stdc++.h> struct Node {    int data;    struct Node* next;    struct Node* bottom;     Node(int x)    {        data = x;        next = NULL;        bottom = NULL;    }}; using namespace std; void flatten(Node* root); int main(void){  //this code builds the flattened linked list  //of first picture in this article ;  Node* head=new Node(5);  auto temp=head;  auto bt=head;  bt->bottom=new Node(7);  bt->bottom->bottom=new Node(8);  bt->bottom->bottom->bottom=new Node(30);  temp->next=new Node(10);     temp=temp->next;  bt=temp;  bt->bottom=new Node(20);  temp->next=new Node(19);  temp=temp->next;  bt=temp;  bt->bottom=new Node(22);  bt->bottom->bottom=new Node(50);  temp->next=new Node(28);  temp=temp->next;  bt=temp;  bt->bottom=new Node(35);  bt->bottom->bottom=new Node(40);  bt->bottom->bottom->bottom=new Node(45);     flatten(head);  cout << endl;  return 0;}   struct mycomp {    bool operator()(Node* a, Node* b)    {        return a->data > b->data;    }};void flatten(Node* root){    priority_queue<Node*, vector<Node*>, mycomp> p;  //pushing main link nodes into priority_queue.    while (root!=NULL) {        p.push(root);        root = root->next;    }       while (!p.empty()) {      //extracting min        auto k = p.top();        p.pop();      //printing  least element        cout << k->data << " ";        if (k->bottom)            p.push(k->bottom);    }    }//this code is contributed by user_990i
5 7 8 10 19 20 22 28 30 35 40 45 50 
Time Complexity: O(N*M*log(N)) – where N is the no of nodes in main linked list (reachable using next pointer) and M is the no of node in a single sub linked list (reachable using bottom pointer).
Explanation:
1. Push all the nodes that are reachable using next pointer into priority queue till we encounter NULL. 
2.while(priority_queue is not empty)
        (i) Extract Node which contains minimum-value(k) from priority_queue and print k->data.
        (ii) If  k->bottom!=NULL ,insert k->bottom into priority_queue. Else our priority_queue size will decrease.
Space Complexity: O(N)-where N is the no of nodes in main linked list (reachable using next pointer).
NOTE: In above explanation, k means the Node which contains minimum-element.
YouTube<div class="player-unavailable"><h1 class="message">An error occurred.</h1><div class="submessage"><a href="https://www.youtube.com/watch?v=PSKZJDtitZw" target="_blank">Try watching this video on www.youtube.com</a>, or enable JavaScript if it is disabled in your browser.</div></div>
kaviarasu
cherry0697
Akanksha_Rai
aashish1995
umadevi9616
maheswaripiyush9
rajsanghavi9
simranarora5sos
tanmayvijay
sagartomar9927
sweetyty
avtarkumar719
user_990i
hardikkoriintern
24*7 Innovation Labs
Amazon
Drishti-Soft
Flipkart
Goldman Sachs
Microsoft
Paytm
Payu
Snapdeal
Visa
Linked List
Paytm
Flipkart
Amazon
Microsoft
Snapdeal
24*7 Innovation Labs
Payu
Visa
Goldman Sachs
Drishti-Soft
Linked List
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Stack Data Structure (Introduction and Program)
LinkedList in Java
Introduction to Data Structures
What is Data Structure: Types, Classifications and Applications
Implementing a Linked List in Java using Class
Add two numbers represented by linked lists | Set 1
Detect and Remove Loop in a Linked List
Queue - Linked List Implementation
Function to check if a singly linked list is palindrome
Implement a stack using singly linked list