C语言链表按指定大小分组反转代码超时求优化
Optimizing Group Reverse for Linked Lists
Hey there! I see your current code for reversing linked list groups works but is slow—let's break down why, then fix it with a much more efficient approach.
What's Wrong with the Current Code?
Your current approach has a few issues that hurt performance and introduce risks:
- Multiple traversals: You first loop through the entire list to count nodes, then loop again to copy data into an array, then loop a third time to write reversed data back. Each traversal adds unnecessary overhead, especially for long lists.
- Fixed-size array: Using
a[1000]means your code will break if the linked list has more than 1000 nodes. It also uses extra memory to store data that we could handle directly on the list. - Logic bug: You modify the original
kvalue withk--in the loop, which breaks subsequent group processing (after the first group,kbecomes 0, so no more groups get processed). That's probably why you're seeing unexpected behavior or extra slowdowns as the code tries to handle broken state.
The Better Approach: In-Place Group Reversal
Instead of copying data to an array, we can reverse each group directly by manipulating pointers. This way we only traverse the list once, use constant extra memory, and avoid the array-related issues.
Here's an optimized iterative implementation:
#include <stdio.h> #include <stdlib.h> struct node { int data; struct node* next; }; // Helper function to reverse a segment of the list void reverseSegment(struct node* start, struct node* end) { struct node* prev = NULL; struct node* curr = start; struct node* next; // Stop when curr reaches the node after end while (curr != end->next) { next = curr->next; curr->next = prev; prev = curr; curr = next; } } struct node* reverse(struct node* head, int k) { if (head == NULL || k == 1) return head; // No need to reverse if k=1 or list is empty struct node dummy; dummy.next = head; struct node* prevGroupTail = &dummy; // Tail of the previous reversed group struct node* curr = head; int count = 0; while (curr != NULL) { count++; // When we reach a group end (or last node if remaining <k) if (count % k == 0 || curr->next == NULL) { struct node* nextGroupHead = curr->next; // Start of next group struct node* currentGroupHead = prevGroupTail->next; // Reverse the current group reverseSegment(currentGroupHead, curr); // Connect previous group to new head of reversed group prevGroupTail->next = curr; // Connect reversed group's tail to next group currentGroupHead->next = nextGroupHead; // Update prevGroupTail for next iteration prevGroupTail = currentGroupHead; curr = nextGroupHead; } else { curr = curr->next; } } return dummy.next; } // Helper function to print the list void printList(struct node* head) { struct node* temp = head; while (temp != NULL) { printf("%d ", temp->data); temp = temp->next; } printf("\n"); } // Helper function to create a node struct node* createNode(int data) { struct node* newNode = (struct node*)malloc(sizeof(struct node)); newNode->data = data; newNode->next = NULL; return newNode; } // Helper function to append a node to the list void appendNode(struct node** head, int data) { struct node* newNode = createNode(data); if (*head == NULL) { *head = newNode; return; } struct node* temp = *head; while (temp->next != NULL) { temp = temp->next; } temp->next = newNode; } int main() { struct node* head = NULL; int n, k, data; printf("Enter number of elements: "); scanf("%d", &n); printf("Enter elements: "); for (int i = 0; i < n; i++) { scanf("%d", &data); appendNode(&head, data); } printf("Enter group size k: "); scanf("%d", &k); head = reverse(head, k); printf("Reversed list: "); printList(head); return 0; }
Key Improvements:
- Single traversal: We process each node exactly once, so time complexity is O(n) with minimal constant overhead.
- In-place operation: No extra array needed—we just rearrange pointers, so space complexity is O(1) (excluding the list itself).
- Handles all cases: Works for lists where the length isn't a multiple of
k(the remaining nodes at the end stay in order), and avoids fixed-size limits. - No logic bugs: We preserve the original
kvalue and correctly link groups after reversal.
Testing this with your example input:
Input: 8 elements [1,2,2,4,5,6,7,8], k=4
Output: 4 2 2 1 8 7 6 5
Which matches your expected result perfectly.
内容的提问来源于stack exchange,提问作者AJITHAN
相关产品推荐
相关产品推荐

