题目:
Given a constant K and a singly linked list L, you are supposed to reverse the links of every K elements on L. For example, given L being 1→2→3→4→5→6, if K = 3, then you must output 3→2→1→6→5→4; if K = 4, you must output 4→3→2→1→5→6.
Input Specification:
Each input file contains one test case. For each case, the first line contains the address of the first node, a positive N (<= 105) which is the total number of nodes, and a positive K (<=N) which is the length of the sublist to be reversed. The address of a node is a 5-digit nonnegative integer, and NULL is represented by -1.
Then N lines follow, each describes a node in the format:
Address Data Next
where Address is the position of the node, Data is an integer, and Next is the position of the next node.
Output Specification:
For each case, output the resulting ordered linked list. Each node occupies a line, and is printed in the same format as in the input.
Sample Input:
00100 6 4 00000 4 99999 00100 1 12309 68237 6 -1 33218 3 00000 99999 5 68237 12309 2 33218
Sample Output:
00000 4 33218 33218 3 12309 12309 2 00100 00100 1 99999 99999 5 68237 68237 6 -1
分析:主要考查链表逆序。 如果通过数组进行排序,然后每K个逆序输出,对于多余的节点将无法通过测试,所以实现必须使用链表。
代码:
typedef struct reverseNode { long address; int value; long nextAdd; struct reverseNode *next; } ReverseNode; ReverseNode *reverseLink(ReverseNode *head, int reverseLen) { ReverseNode *new = head->next; ReverseNode *old = new->next; int count = 1; while (count < reverseLen) { ReverseNode *temp = old->next; old->next = new; old->nextAdd = new->address; new = old; old = temp; count++; } head->next->next = old; if (!old) { head->next->nextAdd = -1; } else { head->next->nextAdd = old->address; } ReverseNode *temp = head->next; head->next = new; head->nextAdd = new->address; return temp; } int main() { // 读取输入 long beginAddress; int number, reverseLen; scanf("%ld %d %d", &beginAddress, &number, &reverseLen); ReverseNode *head = (ReverseNode *)malloc(sizeof(ReverseNode)); ReverseNode *a[number]; for (int i = 0; i < number; i++) { long address, nextAdd; int value; scanf("%ld %d %ld",&address, &value, &nextAdd); ReverseNode *node = (ReverseNode *)malloc(sizeof(ReverseNode)); node->address = address; node->value = value; node->nextAdd = nextAdd; node->next = 0; a[i] = node; if (beginAddress == address) { head->next = node; } } // 对输入数据通过链表连接起来 ReverseNode *temp = head->next; int actualNumber = 1; int recyCount = number; while (temp->nextAdd != -1 && recyCount-- > 0) { for (int i = 0; i < number; i++) { ReverseNode *tempNode = a[i]; if (tempNode->address == temp->nextAdd) { temp->next = tempNode; temp->nextAdd = tempNode->address; temp = temp->next; actualNumber++; break; } } } // 反转 if (reverseLen > 1) { int reverseCount = actualNumber / reverseLen; // 需要进行反转的次数 ReverseNode *tempHead = head; while (reverseCount-- > 0) { tempHead = reverseLink(tempHead, reverseLen); } } ReverseNode *ptr = head->next; while (ptr) { if (ptr->nextAdd == -1) { printf("%.5ld %d -1 ", ptr->address, ptr->value); } else { printf("%.5ld %d %.5ld ", ptr->address, ptr->value, ptr->nextAdd); } ptr = ptr->next; } }
运行结果:
[测试点5,是使用超级大量数据,由于我在将输入数据通过链表连接起来那一步采用的是嵌套循环,复杂度O(N^2),可能是这里导致的,不确定。 但是总体反转思路是这样的,后面找到原因了再进行更新]