Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the algorithm of merging n ascending linked lists #1871

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions Linked_list/Merge_N_Ascending_Linked_Lists/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
This section describes the implementation of a function in C that verifies how to merge n ascending linked lists.
## Problem Statement ##
Gives you an array of linked lists, each of which is already in ascending order.

Please merge all linked lists into an ascending linked list and return the merged linked list.

## Solution ##
Since the linked lists are already sorted, we can use a straightforward approach with a time complexity of O(nk log k), where n is the number of linked lists and k is the average number of nodes in each list.

In the code, we defines a `ListNode` structure for the linked list, a `newNode` function to create new nodes, and the `mergeKLists` function to merge the lists. The `printList` function is used to print the merged list for verification.

Here's the process:

1. **Initialize a Dummy Head**: Create a dummy head node that will serve as the starting point of our merged list. This helps in simplifying the code when dealing with the head of the merged list.

2. **Iterate with a Tail Pointer**: Use a tail pointer to build the merged list. This pointer will always point to the last node in the merged list.

3. **Find the Minimum Node**: In each iteration, we traverse all the linked lists to find the node with the smallest value, keeping track of the smallest node and its index.

4. **Link the Smallest Node**: Once Finding the smallest node, we link it to the tail of the merged list and move the tail pointer to this new node. After linking the smallest node, we can move to the next node in the list from which the smallest node was taken. Continue this process until we have traversed all lists and there are no more nodes to process.

5. **Return the Merged List**: After the loop, we return the next of the dummy head node, which is the head of the merged list.









93 changes: 93 additions & 0 deletions Linked_list/Merge_N_Ascending_Linked_Lists/program.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#include <stdio.h>
#include <stdlib.h>

// Define the structure for a singly linked list node.
struct ListNode {
int val;
struct ListNode *next;
};

// Function to create a new node with given value.
struct ListNode* newNode(int val) {
struct ListNode* node = (struct ListNode*)malloc(sizeof(struct ListNode));
node->val = val;
node->next = NULL;
return node;
}

// Function to merge k sorted linked lists into one sorted linked list.
struct ListNode* mergeKLists(struct ListNode** lists, int k) {
int size = k;
// Dummy head to simplify edge cases.
struct ListNode* dummyHead = newNode(0);
// Tail pointer to build the merged list.
struct ListNode* tail = dummyHead;

while (1) {
// Node with the smallest value.
struct ListNode* minNode = NULL;
// Index of the list containing the minNode.
int minPointer = -1;

for (int i = 0; i < size; i++) {
if (lists[i] == NULL) {
continue;
}
if (minNode == NULL || lists[i]->val < minNode->val) {
minNode = lists[i];
minPointer = i;
}
}

if (minPointer == -1) {
break;
}
// Link the smallest node to the merged list and move the tail pointer.
tail->next = minNode;
tail = tail->next;
// Move to the next node in the list from which minNode was taken.
lists[minPointer] = lists[minPointer]->next;
}

// The merged list starts after the dummy head.
struct ListNode* head = dummyHead->next;
// Free the dummy head as it's not part of the actual list.
free(dummyHead);
return head;
}

// Function to print the linked list starting from the given head node.
void printList(struct ListNode* head) {
while (head) {
printf("%d", head->val);
if (head->next) {
printf("->");
}
head = head->next;
}
printf("\n");
}

// Main function to test the mergeKLists function.
int main() {
// Create three example linked lists.
struct ListNode* l1 = newNode(-1);
l1->next = newNode(4);
l1->next->next = newNode(5);

struct ListNode* l2 = newNode(0);
l2->next = newNode(2);
l2->next->next = newNode(4996);

struct ListNode* l3 = newNode(-10);
l3->next = newNode(8);

struct ListNode* lists[] = {l1, l2, l3};
int k = sizeof(lists) / sizeof(lists[0]);

struct ListNode* mergedList = mergeKLists(lists, k);

printList(mergedList);

return 0;
}
Loading