# Sort numbers stored on different machines

Last Updated : 29 Oct, 2023

Given N machines. Each machine contains some numbers in sorted form. But the amount of numbers, each machine has is not fixed. Output the numbers from all the machine in sorted non-decreasing form.
Example:

`Machine M1 contains 3 numbers: {30, 40, 50}Machine M2 contains 2 numbers: {35, 45} Machine M3 contains 5 numbers: {10, 60, 70, 80, 100}Output: {10, 30, 35, 40, 45, 50, 60, 70, 80, 100}`

Representation of stream of numbers on each machine is considered as a linked list. A Min Heap can be used to print all numbers in sorted order. Following is the detailed process

1. Store the head pointers of the linked lists in a minHeap of size N where N is a number of machines.
2. Extract the minimum item from the minHeap. Update the minHeap by replacing the head of the minHeap with the next number from the linked list or by replacing the head of the minHeap with the last number in the minHeap followed by decreasing the size of heap by 1.
3. Repeat the above step 2 until heap is not empty. Below is C++ implementation of the above approach.

Implementation:

## CPP

 `// A program to take numbers from different machines and print them in sorted order ` `#include `   `// A Linked List node ` `struct` `ListNode ` `{ ` ` ``int` `data; ` ` ``struct` `ListNode* next; ` `}; `   `// A Min Heap Node ` `struct` `MinHeapNode ` `{ ` ` ``ListNode* head; ` `}; `   `// A Min Heao (Collection of Min Heap nodes) ` `struct` `MinHeap ` `{ ` ` ``int` `count; ` ` ``int` `capacity; ` ` ``MinHeapNode* array; ` `}; `   `// A function to create a Min Heap of given capacity ` `MinHeap* createMinHeap( ``int` `capacity ) ` `{ ` ` ``MinHeap* minHeap = ``new` `MinHeap; ` ` ``minHeap->capacity = capacity; ` ` ``minHeap->count = 0; ` ` ``minHeap->array = ``new` `MinHeapNode [minHeap->capacity]; ` ` ``return` `minHeap; ` `} `   `/* A utility function to insert a new node at the beginning ` `of linked list */` `void` `push (ListNode** head_ref, ``int` `new_data) ` `{ ` ` ``/* allocate node */` ` ``ListNode* new_node = ``new` `ListNode; `   ` ``/* put in the data */` ` ``new_node->data = new_data; `   ` ``/* link the old list off the new node */` ` ``new_node->next = (*head_ref); `   ` ``/* move the head to point to the new node */` ` ``(*head_ref) = new_node; ` `} `   `// A utility function to swap two min heap nodes. This function ` `// is needed in minHeapify ` `void` `swap( MinHeapNode* a, MinHeapNode* b ) ` `{ ` ` ``MinHeapNode temp = *a; ` ` ``*a = *b; ` ` ``*b = temp; ` `} `   `// The standard minHeapify function. ` `void` `minHeapify( MinHeap* minHeap, ``int` `idx ) ` `{ ` ` ``int` `left, right, smallest; ` ` ``left = 2 * idx + 1; ` ` ``right = 2 * idx + 2; ` ` ``smallest = idx; `   ` ``if` `( left < minHeap->count && ` `  ``minHeap->array[left].head->data < ` `  ``minHeap->array[smallest].head->data ` ` ``) ` `  ``smallest = left; `   ` ``if` `( right < minHeap->count && ` `  ``minHeap->array[right].head->data < ` `  ``minHeap->array[smallest].head->data ` ` ``) ` `  ``smallest = right; `   ` ``if``( smallest != idx ) ` ` ``{ ` `  ``swap( &minHeap->array[smallest], &minHeap->array[idx] ); ` `  ``minHeapify( minHeap, smallest ); ` ` ``} ` `} `   `// A utility function to check whether a Min Heap is empty or not ` `int` `isEmpty( MinHeap* minHeap ) ` `{ ` ` ``return` `(minHeap->count == 0); ` `} `   `// A standard function to build a heap ` `void` `buildMinHeap( MinHeap* minHeap ) ` `{ ` ` ``int` `i, n; ` ` ``n = minHeap->count - 1; ` ` ``for``( i = (n - 1) / 2; i >= 0; --i ) ` `  ``minHeapify( minHeap, i ); ` `} `   `// This function inserts array elements to heap and then calls ` `// buildHeap for heap property among nodes ` `void` `populateMinHeap( MinHeap* minHeap, ListNode* *array, ``int` `n ) ` `{ ` ` ``for``( ``int` `i = 0; i < n; ++i ) ` `  ``minHeap->array[ minHeap->count++ ].head = array[i]; `   ` ``buildMinHeap( minHeap ); ` `} `   `// Return minimum element from all linked lists ` `ListNode* extractMin( MinHeap* minHeap ) ` `{ ` ` ``if``( isEmpty( minHeap ) ) ` `  ``return` `NULL; `   ` ``// The root of heap will have minimum value ` ` ``MinHeapNode temp = minHeap->array[0]; `   ` ``// Replace root either with next node of the same list. ` ` ``if``( temp.head->next ) ` `  ``minHeap->array[0].head = temp.head->next; ` ` ``else` `// If list empty, then reduce heap size ` ` ``{ ` `  ``minHeap->array[0] = minHeap->array[ minHeap->count - 1 ]; ` `  ``--minHeap->count; ` ` ``} `   ` ``minHeapify( minHeap, 0 ); ` ` ``return` `temp.head; ` `} `   `// The main function that takes an array of lists from N machines ` `// and generates the sorted output ` `void` `externalSort( ListNode *array[], ``int` `N ) ` `{ ` ` ``// Create a min heap of size equal to number of machines ` ` ``MinHeap* minHeap = createMinHeap( N ); `   ` ``// populate first item from all machines ` ` ``populateMinHeap( minHeap, array, N ); `   ` ``while` `( !isEmpty( minHeap ) ) ` ` ``{ ` `  ``ListNode* temp = extractMin( minHeap ); ` `  ``printf``( ``"%d "``,temp->data ); ` ` ``} ` `} `   `// Driver program to test above functions ` `int` `main() ` `{ ` ` ``int` `N = 3; ``// Number of machines `   ` ``// an array of pointers storing the head nodes of the linked lists ` ` ``ListNode *array[N]; `   ` ``// Create a Linked List 30->40->50 for first machine ` ` ``array[0] = NULL; ` ` ``push (&array[0], 50); ` ` ``push (&array[0], 40); ` ` ``push (&array[0], 30); `   ` ``// Create a Linked List 35->45 for second machine ` ` ``array[1] = NULL; ` ` ``push (&array[1], 45); ` ` ``push (&array[1], 35); `   ` ``// Create Linked List 10->60->70->80 for third machine ` ` ``array[2] = NULL; ` ` ``push (&array[2], 100); ` ` ``push (&array[2], 80); ` ` ``push (&array[2], 70); ` ` ``push (&array[2], 60); ` ` ``push (&array[2], 10); `   ` ``// Sort all elements ` ` ``externalSort( array, N ); `   ` ``return` `0; ` `} `

## Java

 `import` `java.util.PriorityQueue;`   `class` `ListNode {` `    ``int` `data;` `    ``ListNode next;`   `    ``public` `ListNode(``int` `data) {` `        ``this``.data = data;` `        ``this``.next = ``null``;` `    ``}` `}`   `class` `MinHeapNode ``implements` `Comparable {` `    ``ListNode head;`   `    ``public` `MinHeapNode(ListNode head) {` `        ``this``.head = head;` `    ``}`   `    ``@Override` `    ``public` `int` `compareTo(MinHeapNode other) {` `        ``return` `this``.head.data - other.head.data;` `    ``}` `}`   `public` `class` `ExternalSort {`   `    ``// Merge K sorted linked lists using a min-heap` `    ``public` `static` `ListNode externalSort(ListNode[] array) {` `        ``PriorityQueue minHeap = ``new` `PriorityQueue<>();`   `        ``// Add the heads of all linked lists to the min-heap` `        ``for` `(ListNode node : array) {` `            ``if` `(node != ``null``) {` `                ``minHeap.offer(``new` `MinHeapNode(node));` `            ``}` `        ``}`   `        ``ListNode dummy = ``new` `ListNode(``0``);` `        ``ListNode tail = dummy;`   `        ``while` `(!minHeap.isEmpty()) {` `            ``MinHeapNode minNode = minHeap.poll();` `            ``tail.next = minNode.head;` `            ``tail = tail.next;`   `            ``if` `(minNode.head.next != ``null``) {` `                ``minHeap.offer(``new` `MinHeapNode(minNode.head.next));` `            ``}` `        ``}`   `        ``return` `dummy.next;` `    ``}`   `    ``public` `static` `void` `printList(ListNode head) {` `        ``while` `(head != ``null``) {` `            ``System.out.print(head.data + ``" "``);` `            ``head = head.next;` `        ``}` `        ``System.out.println();` `    ``}`   `    ``public` `static` `void` `main(String[] args) {` `        ``int` `N = ``3``; ``// Number of machines`   `        ``// An array of pointers storing the head nodes of the linked lists` `        ``ListNode[] array = ``new` `ListNode[N];`   `        ``// Create a Linked List 30->40->50 for the first machine` `        ``array[``0``] = ``new` `ListNode(``30``);` `        ``array[``0``].next = ``new` `ListNode(``40``);` `        ``array[``0``].next.next = ``new` `ListNode(``50``);`   `        ``// Create a Linked List 35->45 for the second machine` `        ``array[``1``] = ``new` `ListNode(``35``);` `        ``array[``1``].next = ``new` `ListNode(``45``);`   `        ``// Create a Linked List 10->60->70->80 for the third machine` `        ``array[``2``] = ``new` `ListNode(``10``);` `        ``array[``2``].next = ``new` `ListNode(``60``);` `        ``array[``2``].next.next = ``new` `ListNode(``70``);` `        ``array[``2``].next.next.next = ``new` `ListNode(``80``);`   `        ``// Sort all elements` `        ``ListNode sortedList = externalSort(array);`   `        ``// Print the sorted list` `        ``System.out.println(``"Sorted List:"``);` `        ``printList(sortedList);` `    ``}` `}`

## Python3

 `# A program to take numbers from different machines and print them in sorted order`   `# A Linked List node` `class` `ListNode:` `    ``def` `__init__(``self``, val``=``0``, ``next``=``None``):` `        ``self``.val ``=` `val` `        ``self``.``next` `=` `next`   `# A Min Heao (Collection of Min Heap nodes)` `class` `MinHeap:` `    ``def` `__init__(``self``, capacity):` `        ``self``.count ``=` `0` `        ``self``.capacity ``=` `capacity` `        ``self``.array ``=` `[]`   `# A utility function to insert a new node at the beginning of linked list` `def` `push(head_ref, new_data):` `    ``new_node ``=` `ListNode(new_data)` `    ``new_node.``next` `=` `head_ref` `    ``head_ref ``=` `new_node` `    ``return` `head_ref`   `# A utility function to swap two min heap nodes. This function` `# is needed in minHeapify` `def` `swap(a, b):` `    ``temp ``=` `a` `    ``a ``=` `b` `    ``b ``=` `temp` `    ``return` `a, b`   `# The standard minHeapify function.` `def` `min_heapify(min_heap, idx):` `    ``left ``=` `2` `*` `idx ``+` `1` `    ``right ``=` `2` `*` `idx ``+` `2` `    ``smallest ``=` `idx`   `    ``if` `(left < min_heap.count ``and` `            ``min_heap.array[left][``0``].val < min_heap.array[smallest][``0``].val):` `        ``smallest ``=` `left` `    ``if` `(right < min_heap.count ``and` `            ``min_heap.array[right][``0``].val < min_heap.array[smallest][``0``].val):` `        ``smallest ``=` `right` `    ``if` `smallest !``=` `idx:` `        ``min_heap.array[smallest], min_heap.array[idx] ``=` `swap(` `            ``min_heap.array[smallest], min_heap.array[idx])` `        ``min_heapify(min_heap, smallest)`   `# A utility function to check whether a Min Heap is empty or not`     `def` `is_empty(min_heap):` `    ``return` `min_heap.count ``=``=` `0`   `# A standard function to build a heap` `def` `build_min_heap(min_heap):` `    ``n ``=` `min_heap.count ``-` `1` `    ``for` `i ``in` `range``((n ``-` `1``) ``/``/` `2``, ``-``1``, ``-``1``):` `        ``min_heapify(min_heap, i)`   `# This function inserts array elements to heap and then calls` `# buildHeap for heap property among nodes` `def` `populate_min_heap(min_heap, array, n):` `    ``for` `i ``in` `range``(n):` `        ``min_heap.array.append((array[i], i))` `        ``min_heap.count ``+``=` `1` `    ``build_min_heap(min_heap)`   `# Return minimum element from all linked lists` `def` `extract_min(min_heap):` `    ``if` `is_empty(min_heap):` `        ``return` `None` `    ``temp ``=` `min_heap.array[``0``][``0``]`   `    ``if` `temp.``next` `is` `not` `None``:` `        ``min_heap.array[``0``] ``=` `(temp.``next``, min_heap.array[``0``][``1``])` `    ``else``:` `        ``min_heap.array[``0``] ``=` `min_heap.array[min_heap.count ``-` `1``]` `        ``min_heap.count ``-``=` `1`   `    ``min_heapify(min_heap, ``0``)` `    ``return` `temp`   `# The main function that takes an array of lists from N machines` `# and generates the sorted output` `def` `external_sort(array, n):` `     ``# Create a min heap of size equal to number of machines` `    ``min_heap ``=` `MinHeap(n)`   `    ``populate_min_heap(min_heap, array, n)`   `    ``while` `not` `is_empty(min_heap):` `        ``temp ``=` `extract_min(min_heap)` `        ``print``(temp.val, end``=``" "``)`     `# Driver program to test above functions` `if` `__name__ ``=``=` `'__main__'``:` `    ``N ``=` `3`  `# Number of machines` `    ``array ``=` `[``None``] ``*` `N`   `    ``# an array of pointers storing the head nodes of the linked lists` `    ``array[``0``] ``=` `None` `    ``array[``0``] ``=` `push(array[``0``], ``50``)` `    ``array[``0``] ``=` `push(array[``0``], ``40``)` `    ``array[``0``] ``=` `push(array[``0``], ``30``)`   `    ``# Create a Linked List 35->45 for second machine` `    ``array[``1``] ``=` `None` `    ``array[``1``] ``=` `push(array[``1``], ``45``)` `    ``array[``1``] ``=` `push(array[``1``], ``35``)`   `    ``# Create Linked List 10->60->70->80 for third machine`   `    ``array[``2``] ``=` `None` `    ``array[``2``] ``=` `push(array[``2``], ``100``)` `    ``array[``2``] ``=` `push(array[``2``], ``80``)` `    ``array[``2``] ``=` `push(array[``2``], ``70``)` `    ``array[``2``] ``=` `push(array[``2``], ``60``)` `    ``array[``2``] ``=` `push(array[``2``], ``10``)`   `    ``external_sort(array, N)`

## C#

 `using` `System;`   `// define a singly linked list node` `public` `class` `ListNode {` `  `  `      ``// data stored in the node` `    ``public` `int` `data;    ` `  `  `      ``// reference to the next node in the linked list` `    ``public` `ListNode next;     ` `}`   `// define a node for the heap, ` `// that holds a reference to a linked list node` `public` `class` `MinHeapNode {` `  `  `      ``// reference to a linked list node` `    ``public` `ListNode head;     ` `}`   `// define the heap data structure` `public` `class` `MinHeap {` `  `  `      ``// number of nodes in the heap` `    ``public` `int` `count;    ` `  `  `      ``// maximum number of nodes the heap can hold` `    ``public` `int` `capacity;  ` `      `  `      ``// an array of MinHeapNode objects, ` `      ``// each containing a linked list node` `    ``public` `MinHeapNode[] array; ` `}`     `public` `class` `ExternalSort {` `    ``static` `MinHeap createMinHeap(``int` `capacity) {` `        ``MinHeap minHeap = ``new` `MinHeap();` `        ``minHeap.capacity = capacity;` `        ``minHeap.count = 0;` `        ``minHeap.array = ``new` `MinHeapNode[minHeap.capacity];` `        ``return` `minHeap;` `    ``}`   `      ``// define a static method to add a new ListNode object ` `      ``// with specified data value to the beginning of a linked list` `    ``static` `void` `push(``ref` `ListNode head_ref, ``int` `new_data) {` `      `  `        ``// create a new ListNode object` `        ``ListNode new_node = ``new` `ListNode();` `      `  `        ``// set the data value and next reference for the new ListNode object` `        ``new_node.data = new_data;` `        ``new_node.next = head_ref;` `      `  `        ``// set the head reference for the linked list to the new ListNode object` `        ``head_ref = new_node;` `    ``}`   `    ``static` `void` `swap(``ref` `MinHeapNode a, ``ref` `MinHeapNode b) {` `        ``MinHeapNode temp = a;` `        ``a = b;` `        ``b = temp;` `    ``}` `  `  `  `  `    ``// define a static method to maintain the min heap property ` `      ``// at a given index in a MinHeap object's array` `    ``static` `void` `minHeapify(MinHeap minHeap, ``int` `idx) {` `        ``int` `left, right, smallest;` `        ``left = 2 * idx + 1;` `        ``right = 2 * idx + 2;` `        ``smallest = idx;`   `        ``if` `(left < minHeap.count &&` `            ``minHeap.array[left].head.data <` `            ``minHeap.array[smallest].head.data) {` `            ``smallest = left;` `        ``}`   `        ``if` `(right < minHeap.count &&` `            ``minHeap.array[right].head.data <` `            ``minHeap.array[smallest].head.data) {` `            ``smallest = right;` `        ``}`   `        ``if` `(smallest != idx) {` `            ``swap(``ref` `minHeap.array[smallest], ``ref` `minHeap.array[idx]);` `            ``minHeapify(minHeap, smallest);` `        ``}` `    ``}`   `      ``// A utility function to check whether a Min Heap is empty or not` `    ``static` `int` `isEmpty(MinHeap minHeap) {` `        ``return` `(minHeap.count == 0) ? 1 : 0;` `    ``}`   `      ``// A standard function to build a heap` `    ``static` `void` `buildMinHeap(MinHeap minHeap) {` `        ``int` `i, n;` `        ``n = minHeap.count - 1;` `        ``for` `(i = (n - 1) / 2; i >= 0; --i) {` `            ``minHeapify(minHeap, i);` `        ``}` `    ``}`   `      ``// This function inserts array elements to heap and then calls` `    ``// buildHeap for heap property among nodes` `    ``static` `void` `populateMinHeap(MinHeap minHeap, ListNode[] array, ``int` `n) {` `        ``for` `(``int` `i = 0; i < n; ++i) {` `            ``MinHeapNode node = ``new` `MinHeapNode();` `            ``node.head = array[i];` `            ``minHeap.array[minHeap.count++] = node;` `        ``}` `        ``buildMinHeap(minHeap);` `    ``}`     `      ``// Return minimum element from all linked lists` `    ``static` `ListNode extractMin(MinHeap minHeap) {` `        ``if` `(isEmpty(minHeap) == 1) {` `            ``return` `null``;` `        ``}`   `        ``MinHeapNode temp = minHeap.array[0];` `        ``ListNode node = temp.head;`   `        ``if` `(temp.head.next == ``null``) {` `            ``minHeap.array[0] = minHeap.array[minHeap.count - 1];` `            ``--minHeap.count;` `        ``}` `        ``else` `{` `            ``minHeap.array[0].head = temp.head.next;` `        ``}`   `        ``minHeapify(minHeap, 0);` `        ``return` `node;` `    ``}`     `      ``// The main function that takes an array of lists from N machines` `    ``// and generates the sorted output` `    ``static` `void` `externalSort(ListNode[] array, ``int` `N) {` `        ``MinHeap minHeap = createMinHeap(N);` `        ``populateMinHeap(minHeap, array, N);`   `        ``while` `(isEmpty(minHeap) != 1) {` `            ``ListNode temp = extractMin(minHeap);` `            ``Console.Write(temp.data + ``" "``);` `        ``}` `    ``}`   `      ``// Driver function` `    ``static` `void` `Main()` `    ``{` `        ``int` `N = 3; ``// Number of machines `   `        ``// an array of pointers storing the head nodes of the linked lists ` `        ``ListNode[] array = ``new` `ListNode[N];`   `        ``// Create a Linked List 30->40->50 for first machine ` `        ``array[0] = ``null``;` `        ``push(``ref` `array[0], 50);` `        ``push(``ref` `array[0], 40);` `        ``push(``ref` `array[0], 30);`   `        ``// Create a Linked List 35->45 for second machine ` `        ``array[1] = ``null``;` `        ``push(``ref` `array[1], 45);` `        ``push(``ref` `array[1], 35);`   `        ``// Create Linked List 10->60->70->80 for third machine ` `        ``array[2] = ``null``;` `        ``push(``ref` `array[2], 100);` `        ``push(``ref` `array[2], 80);` `        ``push(``ref` `array[2], 70);` `        ``push(``ref` `array[2], 60);` `        ``push(``ref` `array[2], 10);`   `        ``// Sort all elements ` `        ``externalSort(array, N);` `    ``}` `}`   `// This code is contributed by amit_mangal_`

## Javascript

 `// A JavaScript program to take numbers from different machines and print them in sorted order`   `// A Linked List node` `class ListNode {` `constructor(val = 0, next = ``null``) {` `this``.val = val;` `this``.next = next;` `}` `}`   `// A Min Heap (Collection of Min Heap nodes)` `class MinHeap {` `constructor(capacity) {` `this``.count = 0;` `this``.capacity = capacity;` `this``.array = [];` `}` `}`   `// A utility function to insert a new node at the beginning of linked list` `function` `push(head_ref, new_data) {` `  ``/* allocate node */` `const new_node = ``new` `ListNode(new_data);` `/* link the old list off the new node */` `new_node.next = head_ref;` `/* move the head to point to the new node */` `head_ref = new_node;` `return` `head_ref;` `}`   `// A utility function to swap two min heap nodes. This function` `// is needed in minHeapify` `function` `swap(a, b) {` `const temp = a;` `a = b;` `b = temp;` `return` `[a, b];` `}`   `// The standard minHeapify function.` `function` `min_heapify(min_heap, idx) {` `const left = 2 * idx + 1;` `const right = 2 * idx + 2;` `let smallest = idx;`   `if` `(` `left < min_heap.count &&` `min_heap.array[left][0].val < min_heap.array[smallest][0].val` `) {` `smallest = left;` `}` `if` `(` `right < min_heap.count &&` `min_heap.array[right][0].val < min_heap.array[smallest][0].val` `) {` `smallest = right;` `}` `if` `(smallest !== idx) {` `[min_heap.array[smallest], min_heap.array[idx]] = swap(` `min_heap.array[smallest],` `min_heap.array[idx]` `);` `min_heapify(min_heap, smallest);` `}` `}`   `// A utility function to check whether a Min Heap is empty or not` `function` `is_empty(min_heap) {` `return` `min_heap.count === 0;` `}`   `// A standard function to build a heap` `function` `build_min_heap(min_heap) {` `const n = min_heap.count - 1;` `for` `(let i = Math.floor((n - 1) / 2); i >= 0; i--) {` `min_heapify(min_heap, i);` `}` `}`   `// This function inserts array elements to heap and then calls` `// buildHeap for heap property among nodes` `function` `populate_min_heap(min_heap, array, n) {` `for` `(let i = 0; i < n; i++) {` `min_heap.array.push([array[i], i]);` `min_heap.count += 1;` `}` `build_min_heap(min_heap);` `}`   `// Return minimum element from all linked lists` `function` `extract_min(min_heap) {` `if` `(is_empty(min_heap)) {` `return` `null``;` `}` `const temp = min_heap.array[0][0];`   `if` `(temp.next !== ``null``) {` `min_heap.array[0] = [temp.next, min_heap.array[0][1]];` `} ``else` `{` `min_heap.array[0] = min_heap.array[min_heap.count - 1];` `min_heap.count -= 1;` `}`   `min_heapify(min_heap, 0);` `return` `temp;` `}`   `// The main function that takes an array of lists from N machines` `// and generates the sorted output` `function` `external_sort(array, n) {` `  ``// Create a min heap of size equal to number of machines` `  ``const min_heap = ``new` `MinHeap(n);`   `  ``populate_min_heap(min_heap, array, n);`   `  ``let sortedList = ``''``;` `  ``while` `(!is_empty(min_heap)) {` `    ``const temp = extract_min(min_heap);` `    ``sortedList += `\${temp.val} `;` `  ``}` `  ``console.log(sortedList.trim());` `}`     `// Driver program to test above functions` `const N = 3; ``// Number of machines` `const array = ``new` `Array(N);`   `// an array of pointers storing the head nodes of the linked lists` `array[0] = ``null``;` `array[0] = push(array[0], 50);` `array[0] = push(array[0], 40);` `array[0] = push(array[0], 30);`   `// Create a Linked List 35->45 for second machine` `array[1] = ``null``;` `array[1] = push(array[1], 45);` `array[1] = push(array[1], 35);`   `// Create Linked List 10->60->70->80 for third machine` `array[2] = ``null``;` `array[2] = push(array[2], 100);` `array[2] = push(array[2], 80);` `array[2] = push(array[2], 70);` `array[2] = push(array[2], 60);` `array[2] = push(array[2], 10);`   `external_sort(array, N);`

Output

```10 30 35 40 45 50 60 70 80 100

```

Time complexity: O(N) for min heap
Auxiliary Space: O(N)

Approach : Using DP

This code uses a priority queue (min heap) to efficiently merge the sorted lists from different machines. The mergeLists function takes a vector of linked lists and merges them into a single sorted linked list using a min heap. The externalSort function converts the array of linked lists into a vector and then calls mergeLists to obtain the sorted list, which is then printed.

Note that this implementation assumes ascending order sorting. If you want to sort in descending order, you can modify the CompareNode struct and change the comparison operator in the operator() function accordingly.

## C++

 `#include ` `#include ` `#include `   `using` `namespace` `std;`   `struct` `ListNode {` `    ``int` `data;` `    ``ListNode* next;` `};`   `struct` `CompareNode {` `    ``bool` `operator()(``const` `ListNode* a, ``const` `ListNode* b) {` `        ``return` `a->data > b->data;` `    ``}` `};`   `ListNode* createNode(``int` `data) {` `    ``ListNode* newNode = ``new` `ListNode;` `    ``newNode->data = data;` `    ``newNode->next = nullptr;` `    ``return` `newNode;` `}`   `void` `push(ListNode** head, ``int` `data) {` `    ``if` `(*head == nullptr) {` `        ``*head = createNode(data);` `    ``} ``else` `{` `        ``ListNode* newNode = createNode(data);` `        ``newNode->next = *head;` `        ``*head = newNode;` `    ``}` `}`   `void` `printList(ListNode* head) {` `    ``while` `(head != nullptr) {` `        ``cout << head->data << ``" "``;` `        ``head = head->next;` `    ``}` `}`   `ListNode* mergeLists(vector& lists) {` `    ``ListNode* dummy = createNode(0);` `    ``ListNode* tail = dummy;`   `    ``priority_queue, CompareNode> minHeap;`   `    ``for` `(ListNode* list : lists) {` `        ``if` `(list != nullptr) {` `            ``minHeap.push(list);` `        ``}` `    ``}`   `    ``while` `(!minHeap.empty()) {` `        ``ListNode* node = minHeap.top();` `        ``minHeap.pop();`   `        ``tail->next = node;` `        ``tail = tail->next;`   `        ``if` `(node->next != nullptr) {` `            ``minHeap.push(node->next);` `        ``}` `    ``}`   `    ``return` `dummy->next;` `}`   `void` `externalSort(ListNode* array[], ``int` `N) {` `    ``vector lists(array, array + N);` `    ``ListNode* sortedList = mergeLists(lists);` `    ``printList(sortedList);` `}`   `int` `main() {` `    ``int` `N = 3; ``// Number of machines`   `    ``ListNode* array[N];`   `    ``array[0] = nullptr;` `    ``push(&array[0], 50);` `    ``push(&array[0], 40);` `    ``push(&array[0], 30);`   `    ``array[1] = nullptr;` `    ``push(&array[1], 45);` `    ``push(&array[1], 35);`   `    ``array[2] = nullptr;` `    ``push(&array[2], 100);` `    ``push(&array[2], 80);` `    ``push(&array[2], 70);` `    ``push(&array[2], 60);` `    ``push(&array[2], 10);`   `    ``externalSort(array, N);`   `    ``return` `0;` `}`

## Java

 `import` `java.util.*;`   `class` `ListNode {` `    ``int` `data;` `    ``ListNode next;`   `    ``ListNode(``int` `data) {` `        ``this``.data = data;` `        ``this``.next = ``null``;` `    ``}` `}`   `class` `CompareNode ``implements` `Comparator {` `    ``@Override` `    ``public` `int` `compare(ListNode a, ListNode b) {` `        ``return` `Integer.compare(a.data, b.data);` `    ``}` `}`   `public` `class` `ExternalSorting {`   `    ``static` `ListNode createNode(``int` `data) {` `        ``return` `new` `ListNode(data);` `    ``}`   `    ``static` `void` `push(ListNode[] head, ``int` `data, ``int` `index) {` `        ``if` `(head[index] == ``null``) {` `            ``head[index] = createNode(data);` `        ``} ``else` `{` `            ``ListNode newNode = createNode(data);` `            ``newNode.next = head[index];` `            ``head[index] = newNode;` `        ``}` `    ``}`   `    ``static` `void` `printList(ListNode head) {` `        ``while` `(head != ``null``) {` `            ``System.out.print(head.data + ``" "``);` `            ``head = head.next;` `        ``}` `    ``}`   `    ``static` `ListNode mergeLists(List lists) {` `        ``ListNode dummy = createNode(``0``);` `        ``ListNode tail = dummy;`   `        ``PriorityQueue minHeap = ``new` `PriorityQueue<>(``new` `CompareNode());`   `        ``for` `(ListNode list : lists) {` `            ``if` `(list != ``null``) {` `                ``minHeap.offer(list);` `            ``}` `        ``}`   `        ``while` `(!minHeap.isEmpty()) {` `            ``ListNode node = minHeap.poll();`   `            ``tail.next = node;` `            ``tail = tail.next;`   `            ``if` `(node.next != ``null``) {` `                ``minHeap.offer(node.next);` `            ``}` `        ``}`   `        ``return` `dummy.next;` `    ``}`   `    ``static` `void` `externalSort(ListNode[] array, ``int` `N) {` `        ``List lists = ``new` `ArrayList<>();` `        ``for` `(ListNode node : array) {` `            ``lists.add(node);` `        ``}` `        ``ListNode sortedList = mergeLists(lists);` `        ``printList(sortedList);` `    ``}`   `    ``public` `static` `void` `main(String[] args) {` `        ``int` `N = ``3``; ``// Number of machines`   `        ``ListNode[] array = ``new` `ListNode[N];`   `        ``array[``0``] = ``null``;` `        ``push(array, ``50``, ``0``);` `        ``push(array, ``40``, ``0``);` `        ``push(array, ``30``, ``0``);`   `        ``array[``1``] = ``null``;` `        ``push(array, ``45``, ``1``);` `        ``push(array, ``35``, ``1``);`   `        ``array[``2``] = ``null``;` `        ``push(array, ``100``, ``2``);` `        ``push(array, ``80``, ``2``);` `        ``push(array, ``70``, ``2``);` `        ``push(array, ``60``, ``2``);` `        ``push(array, ``10``, ``2``);`   `        ``externalSort(array, N);` `    ``}` `}`

## Python3

 `import` `heapq`   `class` `ListNode:` `    ``def` `__init__(``self``, data):` `        ``self``.data ``=` `data` `        ``self``.``next` `=` `None`   `def` `push(head, data):` `    ``# Function to insert a new node at the beginning of a linked list` `    ``new_node ``=` `ListNode(data)` `    ``new_node.``next` `=` `head` `    ``head ``=` `new_node` `    ``return` `head`   `def` `print_list(head):` `    ``# Function to print the linked list` `    ``while` `head:` `        ``print``(head.data, end``=``" "``)` `        ``head ``=` `head.``next` `    ``print``()`   `def` `merge_lists(lists):` `    ``# Function to merge K sorted linked lists into a single sorted linked list` `    ``dummy ``=` `ListNode(``0``)` `    ``tail ``=` `dummy`   `    ``# Use a min heap to keep track of the smallest nodes from each list` `    ``min_heap ``=` `[]`   `    ``for` `lst ``in` `lists:` `        ``if` `lst:` `            ``# Push the first node of each list into the min heap` `            ``heapq.heappush(min_heap, (lst.data, lst))`   `    ``while` `min_heap:` `        ``# Pop the smallest node from the min heap` `        ``data, node ``=` `heapq.heappop(min_heap)`   `        ``# Append the smallest node to the sorted linked list` `        ``tail.``next` `=` `node` `        ``tail ``=` `tail.``next`   `        ``# If the popped node has a next node, push it into the min heap` `        ``if` `node.``next``:` `            ``heapq.heappush(min_heap, (node.``next``.data, node.``next``))`   `    ``return` `dummy.``next`   `def` `external_sort(array):` `    ``# Function to perform external sorting on an array of linked lists` `    ``sorted_list ``=` `merge_lists(array)` `    ``print_list(sorted_list)`   `if` `__name__ ``=``=` `"__main__"``:` `    ``N ``=` `3`  `# Number of machines`   `    ``array ``=` `[``None``] ``*` `N`   `    ``# Create the linked lists for each machine` `    ``array[``0``] ``=` `None` `    ``array[``0``] ``=` `push(array[``0``], ``50``)` `    ``array[``0``] ``=` `push(array[``0``], ``40``)` `    ``array[``0``] ``=` `push(array[``0``], ``30``)`   `    ``array[``1``] ``=` `None` `    ``array[``1``] ``=` `push(array[``1``], ``45``)` `    ``array[``1``] ``=` `push(array[``1``], ``35``)`   `    ``array[``2``] ``=` `None` `    ``array[``2``] ``=` `push(array[``2``], ``100``)` `    ``array[``2``] ``=` `push(array[``2``], ``80``)` `    ``array[``2``] ``=` `push(array[``2``], ``70``)` `    ``array[``2``] ``=` `push(array[``2``], ``60``)` `    ``array[``2``] ``=` `push(array[``2``], ``10``)`   `    ``# Sort all elements` `    ``external_sort(array)`

## C#

 `using` `System;` `using` `System.Collections.Generic;`   `public` `class` `ListNode` `{` `    ``public` `int` `data;` `    ``public` `ListNode next;` `}`   `public` `class` `CompareNode : IComparer` `{` `    ``public` `int` `Compare(ListNode a, ListNode b)` `    ``{` `        ``return` `a.data.CompareTo(b.data);` `    ``}` `}`   `public` `class` `ExternalSortExample` `{` `    ``public` `static` `ListNode CreateNode(``int` `data)` `    ``{` `        ``ListNode newNode = ``new` `ListNode();` `        ``newNode.data = data;` `        ``newNode.next = ``null``;` `        ``return` `newNode;` `    ``}`   `    ``public` `static` `void` `Push(``ref` `ListNode head, ``int` `data)` `    ``{` `        ``if` `(head == ``null``)` `        ``{` `            ``head = CreateNode(data);` `        ``}` `        ``else` `        ``{` `            ``ListNode newNode = CreateNode(data);` `            ``newNode.next = head;` `            ``head = newNode;` `        ``}` `    ``}`   `    ``public` `static` `void` `PrintList(ListNode head)` `    ``{` `        ``while` `(head != ``null``)` `        ``{` `            ``Console.Write(head.data + ``" "``);` `            ``head = head.next;` `        ``}` `    ``}`   `    ``public` `static` `ListNode MergeLists(List lists)` `    ``{` `        ``ListNode dummy = CreateNode(0);` `        ``ListNode tail = dummy;`   `        ``// Create a priority queue using a custom comparer` `        ``PriorityQueue minHeap = ``new` `PriorityQueue(``new` `CompareNode());`   `        ``// Enqueue the initial nodes of all linked lists into the minHeap` `        ``foreach` `(ListNode list ``in` `lists)` `        ``{` `            ``if` `(list != ``null``)` `            ``{` `                ``minHeap.Enqueue(list);` `            ``}` `        ``}`   `        ``// Merge the lists using a min-heap` `        ``while` `(minHeap.Count > 0)` `        ``{` `            ``ListNode node = minHeap.Dequeue();`   `            ``// Append the current node to the merged list` `            ``tail.next = node;` `            ``tail = tail.next;`   `            ``// If the current node has a next node, enqueue the next node` `            ``if` `(node.next != ``null``)` `            ``{` `                ``minHeap.Enqueue(node.next);` `            ``}` `        ``}`   `        ``return` `dummy.next;` `    ``}`   `    ``public` `static` `void` `ExternalSort(ListNode[] array, ``int` `N)` `    ``{` `        ``List lists = ``new` `List(array);` `        ``ListNode sortedList = MergeLists(lists);` `        ``PrintList(sortedList);` `    ``}`   `    ``public` `static` `void` `Main(``string``[] args)` `    ``{` `        ``int` `N = 3; ``// Number of machines`   `        ``// Create an array of ListNode arrays (machines)` `        ``ListNode[] array = ``new` `ListNode[N];`   `        ``// Populate the arrays with data (linked lists)` `        ``array[0] = ``null``;` `        ``Push(``ref` `array[0], 50);` `        ``Push(``ref` `array[0], 40);` `        ``Push(``ref` `array[0], 30);`   `        ``array[1] = ``null``;` `        ``Push(``ref` `array[1], 45);` `        ``Push(``ref` `array[1], 35);`   `        ``array[2] = ``null``;` `        ``Push(``ref` `array[2], 100);` `        ``Push(``ref` `array[2], 80);` `        ``Push(``ref` `array[2], 70);` `        ``Push(``ref` `array[2], 60);` `        ``Push(``ref` `array[2], 10);`   `        ``// Perform external sorting on the arrays (linked lists)` `        ``ExternalSort(array, N);` `    ``}` `}`   `// Priority Queue implementation using SortedSet (C#)` `public` `class` `PriorityQueue` `{` `    ``private` `SortedSet ``set``;` `    ``private` `IComparer comparer;`   `    ``public` `PriorityQueue(IComparer comparer = ``null``)` `    ``{` `        ``this``.comparer = comparer ?? Comparer.Default;` `        ``this``.``set` `= ``new` `SortedSet(``this``.comparer);` `    ``}`   `    ``public` `int` `Count` `    ``{` `        ``get` `{ ``return` `set``.Count; }` `    ``}`   `    ``public` `void` `Enqueue(T item)` `    ``{` `        ``set``.Add(item);` `    ``}`   `    ``public` `T Dequeue()` `    ``{` `        ``if` `(``set``.Count == 0)` `            ``throw` `new` `InvalidOperationException(``"Priority queue is empty."``);` `        ``var` `item = ``set``.Min;` `        ``set``.Remove(item);` `        ``return` `item;` `    ``}` `}`

## Javascript

 `// Define a class for a ListNode, which represents a node in a linked list.` `class ListNode {` `    ``constructor(data) {` `        ``this``.data = data;` `        ``this``.next = ``null``;` `    ``}` `}`   `// Define a class for custom comparison of ListNode objects.` `class CompareNode {` `    ``// Compare function to compare two ListNode objects based on their data values.` `    ``compare(a, b) {` `        ``return` `a.data - b.data;` `    ``}` `}`   `// Define a priority queue class for efficient element management.` `class PriorityQueue {` `    ``constructor(comparator) {` `        ``this``.comparator = comparator || ((a, b) => a - b);` `        ``this``.data = [];` `    ``}`   `    ``// Getter for the count of elements in the priority queue.` `    ``get count() {` `        ``return` `this``.data.length;` `    ``}`   `    ``// Enqueue an item into the priority queue and maintain its order.` `    ``enqueue(item) {` `        ``this``.data.push(item);` `        ``this``.data.sort(``this``.comparator);` `    ``}`   `    ``// Dequeue the item with the highest priority (at the front of the queue).` `    ``dequeue() {` `        ``if` `(``this``.count === 0) {` `            ``throw` `new` `Error(``"Priority queue is empty."``);` `        ``}` `        ``return` `this``.data.shift();` `    ``}` `}`   `// Function to create a new ListNode with the given data.` `function` `createNode(data) {` `    ``return` `new` `ListNode(data);` `}`   `// Function to push a new node with data onto the head of a linked list.` `function` `push(head, data) {` `    ``if` `(!head) {` `        ``return` `createNode(data);` `    ``} ``else` `{` `        ``const newNode = createNode(data);` `        ``newNode.next = head;` `        ``return` `newNode;` `    ``}` `}`   `// Function to print the elements in a linked list.` `function` `printList(head) {` `    ``let current = head;` `    ``while` `(current) {` `        ``console.log(current.data + ``' '``);` `        ``current = current.next;` `    ``}` `}`   `// Function to merge a list of linked lists into a single sorted linked list.` `function` `mergeLists(lists) {` `    ``const dummy = createNode(0);` `    ``let tail = dummy;`   `    ``// Create a priority queue to efficiently manage the elements.` `    ``const minHeap = ``new` `PriorityQueue((a, b) => a.data - b.data);`   `    ``// Enqueue the initial nodes of all linked lists into the priority queue.` `    ``lists.forEach(list => {` `        ``if` `(list !== ``null``) {` `            ``minHeap.enqueue(list);` `        ``}` `    ``});`   `    ``// Merge the lists using the priority queue (min-heap).` `    ``while` `(minHeap.count > 0) {` `        ``const node = minHeap.dequeue();` `        ``tail.next = node;` `        ``tail = tail.next;`   `        ``// If the current node has a next node, enqueue the next node.` `        ``if` `(node.next !== ``null``) {` `            ``minHeap.enqueue(node.next);` `        ``}` `    ``}`   `    ``return` `dummy.next;` `}`   `// Function to perform external sorting on an array of linked lists.` `function` `externalSort(array, N) {` `    ``const lists = array;` `    ``const sortedList = mergeLists(lists);` `    ``printList(sortedList);` `}`   `// Main function where we set up the example and call the externalSort function.` `function` `main() {` `    ``const N = 3; ``// Number of machines`   `    ``// Create an array of linked lists representing data from different machines.` `    ``const array = ``new` `Array(N);`   `    ``// Populate the arrays with data (linked lists).` `    ``array[0] = ``null``;` `    ``array[0] = push(array[0], 50);` `    ``array[0] = push(array[0], 40);` `    ``array[0] = push(array[0], 30);`   `    ``array[1] = ``null``;` `    ``array[1] = push(array[1], 45);` `    ``array[1] = push(array[1], 35);`   `    ``array[2] = ``null``;` `    ``array[2] = push(array[2], 100);` `    ``array[2] = push(array[2], 80);` `    ``array[2] = push(array[2], 70);` `    ``array[2] = push(array[2], 60);` `    ``array[2] = push(array[2], 10);`   `    ``// Perform external sorting on the arrays (linked lists).` `    ``externalSort(array, N);` `}`   `// Call the main function to execute the example.` `main();`

Output:

`10 30 35 40 45 50 60 70 80 100 `

space complexity: O(N + K)

time complexity: O(N + K log N)

Previous Article
Next Article
Article Tags :
Practice Tags :