forked from AlgoGenesis/C
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request AlgoGenesis#1871 from theonlybigmiao/merge_n_ascen…
…ding_linked_lists Add the algorithm of merging n ascending linked lists
- Loading branch information
Showing
2 changed files
with
124 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |