# Merge Sort Explanation with Example In this article, we are going to discuss merge sort and how to merge k sorted lists.

## Merge Sort

• Merge sort is a divide-and-conquer algorithm.
• It is a recursive algorithm.
• In merge sort, we have to divide the container (container can be an array, list, etc.) into two halves then we will call merge sort recursively on the two halves.
• These two merge sort calls return sorted containers, and we then, merge these sorted containers in such a way that the whole container remains sorted.
• Have a look at the below image to see in a nutshell how merge sort works.

Merge sort example:- Now, we have a brief understanding of the merge sort algorithm.

### How to Merge K Sorted Linked Lists

But before learning how to merge k sorted linked lists, we have to first know how to merge two sorted linked lists.

Merging two sorted linked list Algorithm:
When the two recursive call will return the two sorted list, then we will merge those sorted list into a single list using these below steps.

1. Initialize two pointer variable named curr1 and curr2 with left sorted sub-list and right sorted sub-list.
2. Initialize two pointer variable named si and ei with NULL, these two pointer variables are head and tail of the final sorted linked list.
3. If the data of curr1 is less than the data of curr2, then, store curr1 in next of ei & move curr1 to the next of curr1.
4. Else, if the data of curr2 is less than curr1, then store curr2 in next of ei & move curr2 to the next of curr2.
5. Repeat steps 3 and 4 until either the curr1 or curr2 is not equal to null.
6. Now add any remaining nodes of the first or the second linked list to the merged linked list.
7. Return the head of the merged sorted linked list containing all the nodes of the two sorted sub-lists.

We are given k linked lists each of length n. Each given linked list is sorted in non-decreasing order, Our task is to merge them into a single sorted (non-decreasing order) linked list and print the sorted linked list as output.

Examples:
Input:

``````k = 3, n =  3
list1 = 1->3->5->NULL
list2 = 2->4->8->NULL
list3 = 6->7->9->NULL``````

Output:

``1->2->3->4->5->6->7->8->9->NULL``

Input:

``````k = 2, n = 4
list1 = 2->3->10->12->NULL
list2 = 1->4->8->9->NULL``````

Output:

``1->2->3->4->8->9->10->12->NULL``

Min-heap is a min priority queue. It is a complete binary tree having a root value smaller than both children’s values.

``````           2
/   \
4     5
/ \
11  6

Min-Heap``````

We will use a min-heap to get the current minimum value node of linked lists.

### Approach:

The main intuition behind this approach is to maintain the current smallest element from all given linked lists and add that element i.e Node to the final linked list. Let’s understand the algorithm step-wise.

Before understanding the algorithm let’s go briefly through the min-heap data structure. Min-heap data structure is a type of data structure that has the smallest element among all elements in the heap on the top.

### Algorithm:

Create a min-heap of type Node because it will store the nodes of the linked list. First of all, insert the first node of all the ‘k’ linked lists.

Continue these following steps until the min-heap is not empty:-

• Remove the top element of the min-heap (that is the current minimum element in the min-heap).
• Add this node to the result list.
• Push the next node (if exists) of the node (that is popped out from min heap in step1) in the min-heap.

Code:

```#include <bits/stdc++.h>
using namespace std;

struct Node{
int data;
struct Node* next;
};

//function to create a new node
struct Node* newNodeInsert(int data){
// Allocate Node
struct Node* new_node = new Node();

// assigning data of the node
new_node->data = data;
new_node->next = NULL;

return new_node;
}

// 'compare' function used to build up the heap of type min-heap
struct compare{
bool operator()(struct Node* a, struct Node* b){
return a->data > b->data;
}
};

// Function to merge k sorted linked lists
struct Node* mergeKSortedLists(struct Node* lists[], int k){
priority_queue<Node*, vector<Node*>, compare> pq;
//min heap of type pq

// Push the head nodes of all the k lists in 'pq' i.e min-heap
for (int i = 0; i < k; i++){
if (lists[i] != NULL){
pq.push(lists[i]);
}
}

struct Node *ansTail = NULL;

// continue until 'pq' is not empty
while (!pq.empty()){
// Get the top element of min heap
// that's the smallest value node
struct Node* curr = pq.top();
pq.pop();

// Add that node to ans list
}else{
ansTail->next = curr;
ansTail = ansTail->next;
}
// push the next node of the curr->next in the min heap (if exists)
if (curr->next != NULL)
pq.push(curr->next);
}

// merged list
}

// function to print the singly
cout << head->data << " ";
}
return;
}

int main(){
// k is the number of the linked lists and n is the length of the linked list
int k = 3, n = 4;

// lists is array of Node pointer pointing towards head of the linked lists
Node* lists[k];

// Creating k = 3 sorted lists
lists = newNodeInsert(1);
lists->next = newNodeInsert(3);
lists->next->next = newNodeInsert(5);

lists = newNodeInsert(2);
lists->next = newNodeInsert(4);
lists->next->next = newNodeInsert(8);

lists = newNodeInsert(6);
lists->next = newNodeInsert(7);
lists->next->next = newNodeInsert(9);

// Merge the k sorted lists
struct Node* ans = mergeKSortedLists(lists, k);

// Print the final merged list
printList(ans);
}

```

Input:

``````k = 3, n =  3
list1 = 1->3->5->NULL
list2 = 2->4->8->NULL
list3 = 6->7->9->NULL``````

Output:

``1->2->3->4->5->6->7->8->9->NULL``

### Dry Run:  And the above processes will continue like that until the min-heap is empty.

Time Complexity: O(n k log k)
Insertion and deletion in a min-heap require log k time. This process will continue for n* k nodes.

Auxiliary Space: O(k).
The min-heap will have the atmost ‘k’ number of elements at any point in time.