Merge K sorted linked lists
Last Updated :
02 Jan, 2025
Given k sorted linked lists of different sizes, the task is to merge them all maintaining their sorted order.
Examples:
Input:
Output:
Merged lists in a sorted order where every element is greater than the previous element.
Input:
Output:
Merged lists in a sorted order where every element is greater than the previous element.
[Naive Approach - 1] - Merge One by One
The idea is to initialize the result as empty. Now one by one merge every linked list into the resultant list using the idea of merging two sorted linked lists. We always consider the result as first list and other list as second. At the end, we return result.
C++
// C++ program to merge K sorted linked lists
#include <bits/stdc++.h>
using namespace std;
class Node {
public:
int data;
Node* next;
Node(int x) {
data = x;
next = nullptr;
}
};
// Function to merge only 2 lists
Node* mergeTwo(Node* head1, Node* head2) {
// Create a dummy node to simplify
// the merging process
Node* dummy = new Node(-1);
Node* curr = dummy;
// Iterate through both linked lists
while (head1 != nullptr && head2 != nullptr) {
// Add the smaller node to the merged list
if (head1->data <= head2->data) {
curr->next = head1;
head1 = head1->next;
} else {
curr->next = head2;
head2 = head2->next;
}
curr = curr->next;
}
// If any list is left, append it to
// the merged list
if (head1 != nullptr) {
curr->next = head1;
} else {
curr->next = head2;
}
// Return the merged list starting
// from the next of dummy node
return dummy->next;
}
// Function to merge K sorted linked lists
Node* mergeKLists(vector<Node*>& arr) {
// Initialize result as empty
Node *res = nullptr;
// One by one merge all lists with
// res and keep updating res
for (Node *node : arr)
res = mergeTwo(res, node);
return res;
}
void printList(Node* node) {
while (node != nullptr) {
cout << node->data << " ";
node = node->next;
}
}
int main() {
int k = 3;
vector<Node*> arr(k);
arr[0] = new Node(1);
arr[0]->next = new Node(3);
arr[0]->next->next = new Node(5);
arr[0]->next->next->next = new Node(7);
arr[1] = new Node(2);
arr[1]->next = new Node(4);
arr[1]->next->next = new Node(6);
arr[1]->next->next->next = new Node(8);
arr[2] = new Node(0);
arr[2]->next = new Node(9);
arr[2]->next->next = new Node(10);
arr[2]->next->next->next = new Node(11);
Node* head = mergeKLists(arr);
printList(head);
return 0;
}
C
// C program to merge K sorted linked lists
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node* next;
};
struct Node* createNode(int data);
// Function to merge only 2 lists
struct Node* mergeTwo(struct Node* head1, struct Node* head2) {
// Create a dummy node to simplify
// the merging process
struct Node* dummy = createNode(-1);
struct Node* curr = dummy;
// Iterate through both linked lists
while (head1 != NULL && head2 != NULL) {
// Add the smaller node to the merged list
if (head1->data <= head2->data) {
curr->next = head1;
head1 = head1->next;
} else {
curr->next = head2;
head2 = head2->next;
}
curr = curr->next;
}
// If any list is left, append it to
// the merged list
if (head1 != NULL) {
curr->next = head1;
} else {
curr->next = head2;
}
// Return the merged list starting
// from the next of dummy node
struct Node* merged = dummy->next;
free(dummy);
return merged;
}
// Function to merge K sorted linked lists
struct Node* mergeKLists(struct Node** arr, int k) {
// Initialize result as empty
struct Node* res = NULL;
// One by one merge all lists with
// res and keep updating res
for (int i = 0; i < k; i++)
res = mergeTwo(res, arr[i]);
return res;
}
void printList(struct Node* node) {
while (node != NULL) {
printf("%d ", node->data);
node = node->next;
}
}
struct Node* createNode(int data) {
struct Node* newNode =
(struct Node*)malloc(sizeof(struct Node));
newNode->data = data;
newNode->next = NULL;
return newNode;
}
int main() {
int k = 3;
struct Node* arr[k];
arr[0] = createNode(1);
arr[0]->next = createNode(3);
arr[0]->next->next = createNode(5);
arr[0]->next->next->next = createNode(7);
arr[1] = createNode(2);
arr[1]->next = createNode(4);
arr[1]->next->next = createNode(6);
arr[1]->next->next->next = createNode(8);
arr[2] = createNode(0);
arr[2]->next = createNode(9);
arr[2]->next->next = createNode(10);
arr[2]->next->next->next = createNode(11);
struct Node* head = mergeKLists(arr, k);
printList(head);
return 0;
}
Java
// Java program to merge K sorted linked lists
import java.util.List;
import java.util.ArrayList;
class Node {
int data;
Node next;
Node(int x) {
data = x;
next = null;
}
}
class GfG {
// Function to merge only 2 lists
static Node mergeTwo(Node head1, Node head2) {
// Create a dummy node to simplify
// the merging process
Node dummy = new Node(-1);
Node curr = dummy;
// Iterate through both linked lists
while (head1 != null && head2 != null) {
// Add the smaller node to the merged list
if (head1.data <= head2.data) {
curr.next = head1;
head1 = head1.next;
} else {
curr.next = head2;
head2 = head2.next;
}
curr = curr.next;
}
// If any list is left, append it to
// the merged list
if (head1 != null) {
curr.next = head1;
} else {
curr.next = head2;
}
// Return the merged list starting
// from the next of dummy node
return dummy.next;
}
// Function to merge K sorted linked lists
static Node mergeKLists(List<Node> arr) {
// Initialize result as empty
Node res = null;
// One by one merge all lists with
// res and keep updating res
for (Node node : arr)
res = mergeTwo(res, node);
return res;
}
static void printList(Node node) {
while (node != null) {
System.out.print(node.data + " ");
node = node.next;
}
}
public static void main(String[] args) {
List<Node> arr = new ArrayList<>();
arr.add(new Node(1));
arr.get(0).next = new Node(3);
arr.get(0).next.next = new Node(5);
arr.get(0).next.next.next = new Node(7);
arr.add(new Node(2));
arr.get(1).next = new Node(4);
arr.get(1).next.next = new Node(6);
arr.get(1).next.next.next = new Node(8);
arr.add(new Node(0));
arr.get(2).next = new Node(9);
arr.get(2).next.next = new Node(10);
arr.get(2).next.next.next = new Node(11);
Node head = mergeKLists(arr);
printList(head);
}
}
Python
# Python program to merge K sorted linked lists
class Node:
def __init__(self, x):
self.data = x
self.next = None
# Function to merge only 2 lists
def mergeTwo(head1, head2):
# Create a dummy node to simplify
# the merging process
dummy = Node(-1)
curr = dummy
# Iterate through both linked lists
while head1 is not None and head2 is not None:
# Add the smaller node to the merged list
if head1.data <= head2.data:
curr.next = head1
head1 = head1.next
else:
curr.next = head2
head2 = head2.next
curr = curr.next
# If any list is left, append it to
# the merged list
if head1 is not None:
curr.next = head1
else:
curr.next = head2
# Return the merged list starting
# from the next of dummy node
return dummy.next
# Function to merge K sorted linked lists
def mergeKLists(arr):
# Initialize result as empty
res = None
# One by one merge all lists with
# res and keep updating res
for node in arr:
res = mergeTwo(res, node)
return res
def printList(node):
while node is not None:
print(node.data, end=" ")
node = node.next
if __name__ == "__main__":
arr = []
node1 = Node(1)
node1.next = Node(3)
node1.next.next = Node(5)
node1.next.next.next = Node(7)
arr.append(node1)
node2 = Node(2)
node2.next = Node(4)
node2.next.next = Node(6)
node2.next.next.next = Node(8)
arr.append(node2)
node3 = Node(0)
node3.next = Node(9)
node3.next.next = Node(10)
node3.next.next.next = Node(11)
arr.append(node3)
head = mergeKLists(arr)
printList(head)
C#
// C# program to merge K sorted linked lists
using System;
using System.Collections.Generic;
class Node {
public int data;
public Node next;
public Node(int x) {
data = x;
next = null;
}
}
class GfG {
static Node mergeTwo(Node head1, Node head2) {
// Create a dummy node to simplify
// the merging process
Node dummy = new Node(-1);
Node curr = dummy;
// Iterate through both linked lists
while (head1 != null && head2 != null) {
// Add the smaller node to the merged list
if (head1.data <= head2.data) {
curr.next = head1;
head1 = head1.next;
} else {
curr.next = head2;
head2 = head2.next;
}
curr = curr.next;
}
// If any list is left, append it to
// the merged list
if (head1 != null) {
curr.next = head1;
} else {
curr.next = head2;
}
// Return the merged list starting
// from the next of dummy node
return dummy.next;
}
static Node mergeKLists(List<Node> arr) {
// Initialize result as empty
Node res = null;
// One by one merge all lists with
// res and keep updating res
foreach (Node node in arr)
res = mergeTwo(res, node);
return res;
}
static void printList(Node node) {
while (node != null) {
Console.Write(node.data + " ");
node = node.next;
}
}
static void Main(string[] args) {
List<Node> arr = new List<Node>();
Node node1 = new Node(1);
node1.next = new Node(3);
node1.next.next = new Node(5);
node1.next.next.next = new Node(7);
arr.Add(node1);
Node node2 = new Node(2);
node2.next = new Node(4);
node2.next.next = new Node(6);
node2.next.next.next = new Node(8);
arr.Add(node2);
Node node3 = new Node(0);
node3.next = new Node(9);
node3.next.next = new Node(10);
node3.next.next.next = new Node(11);
arr.Add(node3);
Node head = mergeKLists(arr);
printList(head);
}
}
JavaScript
// JavaScript program to merge K sorted linked lists
class Node {
constructor(x) {
this.data = x;
this.next = null;
}
}
// Function to merge only 2 lists
function mergeTwo(head1, head2) {
// Create a dummy node to simplify
// the merging process
let dummy = new Node(-1);
let curr = dummy;
// Iterate through both linked lists
while (head1 !== null && head2 !== null) {
// Add the smaller node to the merged list
if (head1.data <= head2.data) {
curr.next = head1;
head1 = head1.next;
} else {
curr.next = head2;
head2 = head2.next;
}
curr = curr.next;
}
// If any list is left, append it to
// the merged list
if (head1 !== null) {
curr.next = head1;
} else {
curr.next = head2;
}
// Return the merged list starting
// from the next of dummy node
return dummy.next;
}
// Function to merge K sorted linked lists
function mergeKLists(arr) {
// Initialize result as empty
let res = null;
// One by one merge all lists with
// res and keep updating res
for (let node of arr)
res = mergeTwo(res, node);
return res;
}
function printList(node) {
while (node !== null) {
console.log(node.data + " ");
node = node.next;
}
}
let arr = [];
let node1 = new Node(1);
node1.next = new Node(3);
node1.next.next = new Node(5);
node1.next.next.next = new Node(7);
arr.push(node1);
let node2 = new Node(2);
node2.next = new Node(4);
node2.next.next = new Node(6);
node2.next.next.next = new Node(8);
arr.push(node2);
let node3 = new Node(0);
node3.next = new Node(9);
node3.next.next = new Node(10);
node3.next.next.next = new Node(11);
arr.push(node3);
let head = mergeKLists(arr);
printList(head);
Output0 1 2 3 4 5 6 7 8 9 10 11
Time complexity: O(n*k*k), For simplicity, let us assume that every list is of equal size n. In the worst case. we take n + 2n + 3n ..... + k * n time. The sum of this series is n * k * (k + 1) / 2 which is O(n * k * k).
Auxiliary Space: O(1).
[Naive Approach - 2] - Repeatedly Select Min of All Remaining
The idea is to iterate through all the k head nodes and append the head node with minimum value to the resultant list. Increment the head to next node. Repeat this process until all nodes are processed.
Step by step approach:
- Initialize a dummy head for the resultant list.
- Find the node with the smallest value in all the k lists.
- Increment the current pointer to the next node of the list where the smallest node is found.
- Append the node with smallest value to the resultant list.
- Repeat these steps till all nodes have been used.
C++
// C++ program to merge K sorted linked lists
#include <bits/stdc++.h>
using namespace std;
class Node {
public:
int data;
Node* next;
Node(int x) {
data = x;
next = nullptr;
}
};
// Function to get node with minimum value
Node* getMinNode(vector<Node*> &arr) {
Node* mini = nullptr;
int index = -1;
for (int i=0; i<arr.size(); i++) {
// If current list is processed
if (arr[i]==nullptr) continue;
// If min node is not set or
// current head has smaller value.
if (mini==nullptr || arr[i]->data<mini->data) {
index = i;
mini = arr[i];
}
}
// Increment the head node
if (index!=-1) arr[index] = arr[index]->next;
return mini;
}
// Function to merge K sorted linked lists
Node* mergeKLists(vector<Node*>& arr) {
// Create a dummy node to simplify
// the merging process
Node* dummy = new Node(-1);
Node* tail = dummy;
Node* mini = getMinNode(arr);
// Process all nodes.
while (mini != nullptr) {
// Append min node to the result.
tail->next = mini;
tail = mini;
// Find the next min node
mini = getMinNode(arr);
}
// Return the merged list starting
// from the next of dummy node
return dummy->next;
}
void printList(Node* node) {
while (node != nullptr) {
cout << node->data << " ";
node = node->next;
}
}
int main() {
int k = 3;
vector<Node*> arr(k);
arr[0] = new Node(1);
arr[0]->next = new Node(3);
arr[0]->next->next = new Node(5);
arr[0]->next->next->next = new Node(7);
arr[1] = new Node(2);
arr[1]->next = new Node(4);
arr[1]->next->next = new Node(6);
arr[1]->next->next->next = new Node(8);
arr[2] = new Node(0);
arr[2]->next = new Node(9);
arr[2]->next->next = new Node(10);
arr[2]->next->next->next = new Node(11);
Node* head = mergeKLists(arr);
printList(head);
return 0;
}
Java
// Java program to merge K sorted linked lists
import java.util.*;
class Node {
int data;
Node next;
Node(int x) {
data = x;
next = null;
}
}
class GfG {
// Function to get node with minimum value
static Node getMinNode(List<Node> arr) {
Node mini = null;
int index = -1;
for (int i = 0; i < arr.size(); i++) {
// If current list is processed
if (arr.get(i) == null) continue;
// If min node is not set or
// current head has smaller value.
if (mini == null || arr.get(i).data < mini.data) {
index = i;
mini = arr.get(i);
}
}
// Increment the head node
if (index != -1) arr.set(index, arr.get(index).next);
return mini;
}
// Function to merge K sorted linked lists
static Node mergeKLists(List<Node> arr) {
Node dummy = new Node(-1);
Node tail = dummy;
Node mini = getMinNode(arr);
// Process all nodes.
while (mini != null) {
// Append min node to the result.
tail.next = mini;
tail = mini;
// Find the next min node
mini = getMinNode(arr);
}
return dummy.next;
}
static void printList(Node node) {
while (node != null) {
System.out.print(node.data + " ");
node = node.next;
}
}
public static void main(String[] args) {
List<Node> arr = new ArrayList<>();
arr.add(new Node(1));
arr.get(0).next = new Node(3);
arr.get(0).next.next = new Node(5);
arr.get(0).next.next.next = new Node(7);
arr.add(new Node(2));
arr.get(1).next = new Node(4);
arr.get(1).next.next = new Node(6);
arr.get(1).next.next.next = new Node(8);
arr.add(new Node(0));
arr.get(2).next = new Node(9);
arr.get(2).next.next = new Node(10);
arr.get(2).next.next.next = new Node(11);
Node head = mergeKLists(arr);
printList(head);
}
}
Python
# Python program to merge K sorted linked lists
class Node:
def __init__(self, x):
self.data = x
self.next = None
# Function to get node with minimum value
def getMinNode(arr):
mini = None
index = -1
for i in range(len(arr)):
# If current list is processed
if arr[i] is None:
continue
# If min node is not set or
# current head has smaller value.
if mini is None or arr[i].data < mini.data:
index = i
mini = arr[i]
# Increment the head node
if index != -1:
arr[index] = arr[index].next
return mini
# Function to merge K sorted linked lists
def mergeKLists(arr):
dummy = Node(-1)
tail = dummy
mini = getMinNode(arr)
# Process all nodes.
while mini:
# Append min node to the result.
tail.next = mini
tail = mini
# Find the next min node
mini = getMinNode(arr)
return dummy.next
def printList(node):
while node:
print(node.data, end=" ")
node = node.next
if __name__ == "__main__":
arr = [None] * 3
arr[0] = Node(1)
arr[0].next = Node(3)
arr[0].next.next = Node(5)
arr[0].next.next.next = Node(7)
arr[1] = Node(2)
arr[1].next = Node(4)
arr[1].next.next = Node(6)
arr[1].next.next.next = Node(8)
arr[2] = Node(0)
arr[2].next = Node(9)
arr[2].next.next = Node(10)
arr[2].next.next.next = Node(11)
head = mergeKLists(arr)
printList(head)
C#
// C# program to merge K sorted linked lists
using System;
using System.Collections.Generic;
class Node {
public int data;
public Node next;
public Node(int x) {
data = x;
next = null;
}
}
class GfG {
// Function to get node with minimum value
static Node getMinNode(List<Node> arr) {
Node mini = null;
int index = -1;
for (int i = 0; i < arr.Count; i++) {
// If current list is processed
if (arr[i] == null) continue;
// If min node is not set or
// current head has smaller value.
if (mini == null || arr[i].data < mini.data) {
index = i;
mini = arr[i];
}
}
// Increment the head node
if (index != -1) arr[index] = arr[index].next;
return mini;
}
// Function to merge K sorted linked lists
static Node mergeKLists(List<Node> arr) {
Node dummy = new Node(-1);
Node tail = dummy;
Node mini = getMinNode(arr);
// Process all nodes.
while (mini != null) {
// Append min node to the result.
tail.next = mini;
tail = mini;
// Find the next min node
mini = getMinNode(arr);
}
return dummy.next;
}
static void printList(Node node) {
while (node != null) {
Console.Write(node.data + " ");
node = node.next;
}
}
static void Main() {
List<Node> arr = new List<Node>();
arr.Add(new Node(1));
arr[0].next = new Node(3);
arr[0].next.next = new Node(5);
arr[0].next.next.next = new Node(7);
arr.Add(new Node(2));
arr[1].next = new Node(4);
arr[1].next.next = new Node(6);
arr[1].next.next.next = new Node(8);
arr.Add(new Node(0));
arr[2].next = new Node(9);
arr[2].next.next = new Node(10);
arr[2].next.next.next = new Node(11);
Node head = mergeKLists(arr);
printList(head);
}
}
JavaScript
// JavaScript program to merge K sorted linked lists
class Node {
constructor(x) {
this.data = x;
this.next = null;
}
}
// Function to get node with minimum value
function getMinNode(arr) {
let mini = null;
let index = -1;
for (let i = 0; i < arr.length; i++) {
// If current list is processed
if (arr[i] === null) continue;
// If min node is not set or
// current head has smaller value.
if (mini === null || arr[i].data < mini.data) {
index = i;
mini = arr[i];
}
}
// Increment the head node
if (index !== -1) arr[index] = arr[index].next;
return mini;
}
// Function to merge K sorted linked lists
function mergeKLists(arr) {
let dummy = new Node(-1);
let tail = dummy;
let mini = getMinNode(arr);
// Process all nodes.
while (mini !== null) {
// Append min node to the result.
tail.next = mini;
tail = mini;
// Find the next min node
mini = getMinNode(arr);
}
return dummy.next;
}
function printList(node) {
while (node !== null) {
console.log(node.data + " ");
node = node.next;
}
}
let arr = [];
arr.push(new Node(1));
arr[0].next = new Node(3);
arr[0].next.next = new Node(5);
arr[0].next.next.next = new Node(7);
arr.push(new Node(2));
arr[1].next = new Node(4);
arr[1].next.next = new Node(6);
arr[1].next.next.next = new Node(8);
arr.push(new Node(0));
arr[2].next = new Node(9);
arr[2].next.next = new Node(10);
arr[2].next.next.next = new Node(11);
let head = mergeKLists(arr);
printList(head);
Output0 1 2 3 4 5 6 7 8 9 10 11
Time complexity: O(n * k2), There are n*k nodes in total (assuming every list has O(n) nodes) and to find the smallest node it takes k times so for the n*k nodes it will take n*k*k time.
Auxiliary Space: O(1)
[Expected Approach - 1] - Using Min Heap (Works better for unequal sized lists)
This solution is mainly an optimization over the previous approach. Instead of linearly traversing the array to find the minimum, we use min heap data structure and reduce the time complexity of this operation to O(Log k).
For a more detailed solution and code, refer to article Merge k sorted linked lists Using Min Heap.
Time Complexity: O(n * k * log k) if we have k lists of size O(n) each. We can also say O(n * Log k) where n is the total number of nodes.
Auxiliary Space: O(k)
[Expected Approach - 2] - Using Divide and Conquer (Works better for equal sized lists)
The idea is to use divide and conquer by recursively splitting the k lists into two halves until we have pairs of lists to merge, then merge these pairs using a two-way merge procedure (similar to merge sort's merge step), and continue this process back up through the recursion tree until all lists are merged into a single sorted list.
Step by step approach:
- Split k lists into two parts: lists[0...mid] and lists[mid+1...end].
- Recursively merge the left half of lists to get first sorted list.
- Recursively merge the right half of lists to get second sorted list.
- Merge the above two sorted lists using two-pointer approach.
- Return the final merged sorted list.
C++
// C++ program to merge K sorted linked lists
#include <bits/stdc++.h>
using namespace std;
class Node {
public:
int data;
Node* next;
Node(int x) {
data = x;
next = nullptr;
}
};
// Function to merge two sorted lists.
Node* mergeTwo(Node* head1, Node* head2) {
// Create a dummy node to simplify
// the merging process
Node* dummy = new Node(-1);
Node* curr = dummy;
// Iterate through both linked lists
while (head1 != nullptr && head2 != nullptr) {
// Add the smaller node to the merged list
if (head1->data <= head2->data) {
curr->next = head1;
head1 = head1->next;
} else {
curr->next = head2;
head2 = head2->next;
}
curr = curr->next;
}
// If any list is left, append it to
// the merged list
if (head1 != nullptr) {
curr->next = head1;
} else {
curr->next = head2;
}
// Return the merged list starting
// from the next of dummy node
return dummy->next;
}
Node* mergeListsRecur(int i, int j, vector<Node*> &arr) {
// If single list is left
if (i == j) return arr[i];
// Find the middle of lists
int mid = i + (j-i)/2;
// Merge lists from i to mid
Node* head1 = mergeListsRecur(i, mid, arr);
// Merge lists from mid+1 to j
Node* head2 = mergeListsRecur(mid+1, j, arr);
// Merge the above 2 lists
Node* head = mergeTwo(head1, head2);
return head;
}
// Function to merge K sorted linked lists
Node* mergeKLists(vector<Node*>& arr) {
// Base case for 0 lists
if (arr.size()==0) return nullptr;
return mergeListsRecur(0, arr.size()-1, arr);
}
void printList(Node* node) {
while (node != nullptr) {
cout << node->data << " ";
node = node->next;
}
}
int main() {
int k = 3;
vector<Node*> arr(k);
arr[0] = new Node(1);
arr[0]->next = new Node(3);
arr[0]->next->next = new Node(5);
arr[0]->next->next->next = new Node(7);
arr[1] = new Node(2);
arr[1]->next = new Node(4);
arr[1]->next->next = new Node(6);
arr[1]->next->next->next = new Node(8);
arr[2] = new Node(0);
arr[2]->next = new Node(9);
arr[2]->next->next = new Node(10);
arr[2]->next->next->next = new Node(11);
Node* head = mergeKLists(arr);
printList(head);
return 0;
}
Java
// Java program to merge K sorted linked lists
import java.util.List;
class Node {
int data;
Node next;
Node(int x) {
data = x;
next = null;
}
}
class GfG {
// Function to merge two sorted lists.
static Node mergeTwo(Node head1, Node head2) {
// Create a dummy node to simplify
// the merging process
Node dummy = new Node(-1);
Node curr = dummy;
// Iterate through both linked lists
while (head1 != null && head2 != null) {
// Add the smaller node to the merged list
if (head1.data <= head2.data) {
curr.next = head1;
head1 = head1.next;
} else {
curr.next = head2;
head2 = head2.next;
}
curr = curr.next;
}
// If any list is left, append it to
// the merged list
if (head1 != null) {
curr.next = head1;
} else {
curr.next = head2;
}
// Return the merged list starting
// from the next of dummy node
return dummy.next;
}
static Node mergeListsRecur(int i, int j, List<Node> arr) {
// If single list is left
if (i == j) return arr.get(i);
// Find the middle of lists
int mid = i + (j - i) / 2;
// Merge lists from i to mid
Node head1 = mergeListsRecur(i, mid, arr);
// Merge lists from mid+1 to j
Node head2 = mergeListsRecur(mid + 1, j, arr);
// Merge the above 2 lists
Node head = mergeTwo(head1, head2);
return head;
}
// Function to merge K sorted linked lists
static Node mergeKLists(List<Node> arr) {
// Base case for 0 lists
if (arr.size() == 0) return null;
return mergeListsRecur(0, arr.size() - 1, arr);
}
static void printList(Node node) {
while (node != null) {
System.out.print(node.data + " ");
node = node.next;
}
}
public static void main(String[] args) {
int k = 3;
List<Node> arr = new java.util.ArrayList<>();
arr.add(new Node(1));
arr.get(0).next = new Node(3);
arr.get(0).next.next = new Node(5);
arr.get(0).next.next.next = new Node(7);
arr.add(new Node(2));
arr.get(1).next = new Node(4);
arr.get(1).next.next = new Node(6);
arr.get(1).next.next.next = new Node(8);
arr.add(new Node(0));
arr.get(2).next = new Node(9);
arr.get(2).next.next = new Node(10);
arr.get(2).next.next.next = new Node(11);
Node head = mergeKLists(arr);
printList(head);
}
}
Python
# Python program to merge K sorted linked lists
class Node:
def __init__(self, x):
self.data = x
self.next = None
# Function to merge two sorted lists.
def mergeTwo(head1, head2):
# Create a dummy node to simplify
# the merging process
dummy = Node(-1)
curr = dummy
# Iterate through both linked lists
while head1 is not None and head2 is not None:
# Add the smaller node to the merged list
if head1.data <= head2.data:
curr.next = head1
head1 = head1.next
else:
curr.next = head2
head2 = head2.next
curr = curr.next
# If any list is left, append it to
# the merged list
if head1 is not None:
curr.next = head1
else:
curr.next = head2
# Return the merged list starting
# from the next of dummy node
return dummy.next
def mergeListsRecur(i, j, arr):
# If single list is left
if i == j:
return arr[i]
# Find the middle of lists
mid = i + (j - i) // 2
# Merge lists from i to mid
head1 = mergeListsRecur(i, mid, arr)
# Merge lists from mid+1 to j
head2 = mergeListsRecur(mid + 1, j, arr)
# Merge the above 2 lists
head = mergeTwo(head1, head2)
return head
# Function to merge K sorted linked lists
def mergeKLists(arr):
# Base case for 0 lists
if len(arr) == 0:
return None
return mergeListsRecur(0, len(arr) - 1, arr)
def printList(node):
while node is not None:
print(node.data, end=" ")
node = node.next
if __name__ == "__main__":
k = 3
arr = [None] * k
arr[0] = Node(1)
arr[0].next = Node(3)
arr[0].next.next = Node(5)
arr[0].next.next.next = Node(7)
arr[1] = Node(2)
arr[1].next = Node(4)
arr[1].next.next = Node(6)
arr[1].next.next.next = Node(8)
arr[2] = Node(0)
arr[2].next = Node(9)
arr[2].next.next = Node(10)
arr[2].next.next.next = Node(11)
head = mergeKLists(arr)
printList(head)
C#
// C# program to merge K sorted linked lists
using System;
using System.Collections.Generic;
class Node {
public int data;
public Node next;
public Node(int x) {
data = x;
next = null;
}
}
class GfG {
// Function to merge two sorted lists.
static Node mergeTwo(Node head1, Node head2) {
// Create a dummy node to simplify
// the merging process
Node dummy = new Node(-1);
Node curr = dummy;
// Iterate through both linked lists
while (head1 != null && head2 != null) {
// Add the smaller node to the merged list
if (head1.data <= head2.data) {
curr.next = head1;
head1 = head1.next;
} else {
curr.next = head2;
head2 = head2.next;
}
curr = curr.next;
}
// If any list is left, append it to
// the merged list
if (head1 != null) {
curr.next = head1;
} else {
curr.next = head2;
}
// Return the merged list starting
// from the next of dummy node
return dummy.next;
}
static Node mergeListsRecur(int i, int j, List<Node> arr) {
// If single list is left
if (i == j) return arr[i];
// Find the middle of lists
int mid = i + (j - i) / 2;
// Merge lists from i to mid
Node head1 = mergeListsRecur(i, mid, arr);
// Merge lists from mid+1 to j
Node head2 = mergeListsRecur(mid + 1, j, arr);
// Merge the above 2 lists
Node head = mergeTwo(head1, head2);
return head;
}
// Function to merge K sorted linked lists
static Node mergeKLists(List<Node> arr) {
// Base case for 0 lists
if (arr.Count == 0) return null;
return mergeListsRecur(0, arr.Count - 1, arr);
}
static void printList(Node node) {
while (node != null) {
Console.Write(node.data + " ");
node = node.next;
}
}
static void Main(string[] args) {
List<Node> arr = new List<Node>();
arr.Add(new Node(1));
arr[0].next = new Node(3);
arr[0].next.next = new Node(5);
arr[0].next.next.next = new Node(7);
arr.Add(new Node(2));
arr[1].next = new Node(4);
arr[1].next.next = new Node(6);
arr[1].next.next.next = new Node(8);
arr.Add(new Node(0));
arr[2].next = new Node(9);
arr[2].next.next = new Node(10);
arr[2].next.next.next = new Node(11);
Node head = mergeKLists(arr);
printList(head);
}
}
JavaScript
// JavaScript program to merge K sorted linked lists
class Node {
constructor(x) {
this.data = x;
this.next = null;
}
}
// Function to merge two sorted lists.
function mergeTwo(head1, head2) {
// Create a dummy node to simplify
// the merging process
let dummy = new Node(-1);
let curr = dummy;
// Iterate through both linked lists
while (head1 !== null && head2 !== null) {
// Add the smaller node to the merged list
if (head1.data <= head2.data) {
curr.next = head1;
head1 = head1.next;
} else {
curr.next = head2;
head2 = head2.next;
}
curr = curr.next;
}
// If any list is left, append it to
// the merged list
if (head1 !== null) {
curr.next = head1;
} else {
curr.next = head2;
}
// Return the merged list starting
// from the next of dummy node
return dummy.next;
}
function mergeListsRecur(i, j, arr) {
// If single list is left
if (i === j) return arr[i];
// Find the middle of lists
let mid = i + Math.floor((j - i) / 2);
// Merge lists from i to mid
let head1 = mergeListsRecur(i, mid, arr);
// Merge lists from mid+1 to j
let head2 = mergeListsRecur(mid + 1, j, arr);
// Merge the above 2 lists
return mergeTwo(head1, head2);
}
// Function to merge K sorted linked lists
function mergeKLists(arr) {
// Base case for 0 lists
if (arr.length === 0) return null;
return mergeListsRecur(0, arr.length - 1, arr);
}
function printList(node) {
while (node !== null) {
console.log(node.data + " ");
node = node.next;
}
}
let k = 3;
let arr = [];
arr[0] = new Node(1);
arr[0].next = new Node(3);
arr[0].next.next = new Node(5);
arr[0].next.next.next = new Node(7);
arr[1] = new Node(2);
arr[1].next = new Node(4);
arr[1].next.next = new Node(6);
arr[1].next.next.next = new Node(8);
arr[2] = new Node(0);
arr[2].next = new Node(9);
arr[2].next.next = new Node(10);
arr[2].next.next.next = new Node(11);
let head = mergeKLists(arr);
printList(head);
Output0 1 2 3 4 5 6 7 8 9 10 11
Time Complexity: O(n * k * log k), where n is the number of nodes in the longest list.
Auxiliary Space: O(log k), used for recursion.
Similar Reads
Merge Sort - Data Structure and Algorithms Tutorials Merge sort is a popular sorting algorithm known for its efficiency and stability. It follows the divide-and-conquer approach. It works by recursively dividing the input array into two halves, recursively sorting the two halves and finally merging them back together to obtain the sorted array. Merge
14 min read
Merge sort in different languages
C Program for Merge SortMerge Sort is a comparison-based sorting algorithm that works by dividing the input array into two halves, then calling itself for these two halves, and finally it merges the two sorted halves. In this article, we will learn how to implement merge sort in C language.What is Merge Sort Algorithm?Merg
3 min read
C++ Program For Merge SortMerge Sort is a comparison-based sorting algorithm that uses divide and conquer paradigm to sort the given dataset. It divides the dataset into two halves, calls itself for these two halves, and then it merges the two sorted halves.In this article, we will learn how to implement merge sort in a C++
4 min read
Java Program for Merge SortMerge Sort is a divide-and-conquer algorithm. It divides the input array into two halves, calls itself the two halves, and then merges the two sorted halves. The merge() function is used for merging two halves. The merge(arr, l, m, r) is a key process that assumes that arr[l..m] and arr[m+1..r] are
3 min read
Merge Sort in PythonMerge Sort is a Divide and Conquer algorithm. It divides input array in two halves, calls itself for the two halves and then merges the two sorted halves. The merge() function is used for merging two halves. The merge(arr, l, m, r) is key process that assumes that arr[l..m] and arr[m+1..r] are sorte
4 min read
Merge Sort using Multi-threadingMerge Sort is a popular sorting technique which divides an array or list into two halves and then start merging them when sufficient depth is reached. Time complexity of merge sort is O(nlogn).Threads are lightweight processes and threads shares with other threads their code section, data section an
14 min read
Variations of Merge Sort
3-way Merge SortMerge Sort is a divide-and-conquer algorithm that recursively splits an array into two halves, sorts each half, and then merges them. A variation of this is 3-way Merge Sort, where instead of splitting the array into two parts, we divide it into three equal parts. In traditional Merge Sort, the arra
13 min read
Iterative Merge SortGiven an array of size n, the task is to sort the given array using iterative merge sort.Examples:Input: arr[] = [4, 1, 3, 9, 7]Output: [1, 3, 4, 7, 9]Explanation: The output array is sorted.Input: arr[] = [1, 3 , 2]Output: [1, 2, 3]Explanation: The output array is sorted.You can refer to Merge Sort
9 min read
In-Place Merge SortImplement Merge Sort i.e. standard implementation keeping the sorting algorithm as in-place. In-place means it does not occupy extra memory for merge operation as in the standard case. Examples: Input: arr[] = {2, 3, 4, 1} Output: 1 2 3 4 Input: arr[] = {56, 2, 45} Output: 2 45 56 Approach 1: Mainta
15+ min read
In-Place Merge Sort | Set 2Given an array A[] of size N, the task is to sort the array in increasing order using In-Place Merge Sort. Examples: Input: A = {5, 6, 3, 2, 1, 6, 7}Output: {1, 2, 3, 5, 6, 6, 7} Input: A = {2, 3, 4, 1}Output: {1, 2, 3, 4} Approach: The idea is to use the inplace_merge() function to merge the sorted
7 min read
Merge Sort with O(1) extra space merge and O(n log n) time [Unsigned Integers Only]We have discussed Merge sort. How to modify the algorithm so that merge works in O(1) extra space and algorithm still works in O(n Log n) time. We may assume that the input values are integers only. Examples: Input : 5 4 3 2 1 Output : 1 2 3 4 5 Input : 999 612 589 856 56 945 243 Output : 56 243 589
10 min read
Merge Sort in Linked List
Find a permutation that causes worst case of Merge Sort Given a set of elements, find which permutation of these elements would result in worst case of Merge Sort.Asymptotically, merge sort always takes O(n Log n) time, but the cases that require more comparisons generally take more time in practice. We basically need to find a permutation of input eleme
12 min read
How to make Mergesort to perform O(n) comparisons in best case? As we know, Mergesort is a divide and conquer algorithm that splits the array to halves recursively until it reaches an array of the size of 1, and after that it merges sorted subarrays until the original array is fully sorted. Typical implementation of merge sort works in O(n Log n) time in all thr
3 min read
Concurrent Merge Sort in Shared Memory Given a number 'n' and a n numbers, sort the numbers using Concurrent Merge Sort. (Hint: Try to use shmget, shmat system calls).Part1: The algorithm (HOW?) Recursively make two child processes, one for the left half, one of the right half. If the number of elements in the array for a process is less
10 min read
Visualization of Merge Sort
Some problems on Merge Sort
Count Inversions of an ArrayGiven an integer array arr[] of size n, find the inversion count in the array. Two array elements arr[i] and arr[j] form an inversion if arr[i] > arr[j] and i < j.Note: Inversion Count for an array indicates that how far (or close) the array is from being sorted. If the array is already sorted
15+ min read
Count of smaller elements on right side of each element in an Array using Merge sortGiven an array arr[] of N integers, the task is to count the number of smaller elements on the right side for each of the element in the array Examples: Input: arr[] = {6, 3, 7, 2} Output: 2, 1, 1, 0 Explanation: Smaller elements after 6 = 2 [3, 2] Smaller elements after 3 = 1 [2] Smaller elements a
12 min read
Sort a nearly sorted (or K sorted) arrayGiven an array arr[] and a number k . The array is sorted in a way that every element is at max k distance away from it sorted position. It means if we completely sort the array, then the index of the element can go from i - k to i + k where i is index in the given array. Our task is to completely s
6 min read
Median of two Sorted Arrays of Different SizesGiven two sorted arrays, a[] and b[], the task is to find the median of these sorted arrays. Assume that the two sorted arrays are merged and then median is selected from the combined array.This is an extension of Median of two sorted arrays of equal size problem. Here we handle arrays of unequal si
15+ min read
Merge k Sorted ArraysGiven K sorted arrays, merge them and print the sorted output.Examples:Input: K = 3, arr = { {1, 3, 5, 7}, {2, 4, 6, 8}, {0, 9, 10, 11}}Output: 0 1 2 3 4 5 6 7 8 9 10 11 Input: k = 4, arr = { {1}, {2, 4}, {3, 7, 9, 11}, {13} }Output: 1 2 3 4 7 9 11 13Table of ContentNaive - Concatenate all and SortU
15+ min read
Merge K sorted arrays of different sizes | ( Divide and Conquer Approach )Given k sorted arrays of different length, merge them into a single array such that the merged array is also sorted.Examples: Input : {{3, 13}, {8, 10, 11} {9, 15}} Output : {3, 8, 9, 10, 11, 13, 15} Input : {{1, 5}, {2, 3, 4}} Output : {1, 2, 3, 4, 5} Let S be the total number of elements in all th
8 min read
Merge K sorted linked listsGiven k sorted linked lists of different sizes, the task is to merge them all maintaining their sorted order.Examples: Input: Output: Merged lists in a sorted order where every element is greater than the previous element.Input: Output: Merged lists in a sorted order where every element is greater t
15+ min read
Union and Intersection of two Linked List using Merge SortGiven two singly Linked Lists, create union and intersection lists that contain the union and intersection of the elements present in the given lists. Each of the two lists contains distinct node values.Note: The order of elements in output lists doesn't matter.Examples:Input: head1: 10 -> 15 -
15+ min read
Sorting by combining Insertion Sort and Merge Sort algorithmsInsertion sort: The array is virtually split into a sorted and an unsorted part. Values from the unsorted part are picked and placed at the correct position in the sorted part.Advantages: Following are the advantages of insertion sort: If the size of the list to be sorted is small, insertion sort ru
2 min read
Find array with k number of merge sort callsGiven two numbers n and k, find an array containing values in [1, n] and requires exactly k calls of recursive merge sort function. Examples: Input : n = 3 k = 3 Output : a[] = {2, 1, 3} Explanation: Here, a[] = {2, 1, 3} First of all, mergesort(0, 3) will be called, which then sets mid = 1 and call
6 min read
Difference of two Linked Lists using Merge sortGiven two Linked List, the task is to create a Linked List to store the difference of Linked List 1 with Linked List 2, i.e. the elements present in List 1 but not in List 2.Examples: Input: List1: 10 -> 15 -> 4 ->20, List2: 8 -> 4 -> 2 -> 10 Output: 15 -> 20 Explanation: In the
14 min read