02-线性结构3 Reversing Linked List (25分)

    技术2025-12-03  17

    02-线性结构3 Reversing Linked List (25分)

    主要思路: 用一个结构数组把输入的各个节点存储起来,注意可能有些节点的地址没有通过结构中的地址串起来,把所有节点的Index成员全部设为0;然后循环遍历这个数组,根据首地址依次找到各个节点,按顺序给这些节点的Index成员依次赋值为1,2,3,…,cnt;创建一个新的长度为cnt+1的结构数组Lib用于存储排好序的可用节点,将不可用节点存在0位置;最后根据反转间距数K,每次提取K个节点,根据排好序的Lib数组来进行反转输出。 反转输出时要注意两点: 1⃣️反转之后的Next应该是下一个应输出节点的Address,而不是当前节点的Next,因为反转之后的Next是改变了的; 2⃣️每K个节点中的最后一个反转节点的下一个元素的Address的的确定需要分三种情况讨论:1.最后反转节点刚好是整个数组的最后一个节点,则最后应输出的Next为-1;2.最后反转节点不是最后一个节点,且剩余未反转节点不少于K,因此仍需继续取K个节点进行反转输出,此时最后应输出的Next应为接下来K个节点中最后一个节点的Address;3.最后反转节点不是最后一个节点,且剩余未反转节点少于K,则剩余节点不需要反转,此时最应输出的Next为剩余节点的第一个节点的Address。

    代码如下

    #include <stdio.h> struct Node { int Address; int Data; int Next; int Index; }; int main() { int first, N, K; scanf("%d %d %d", &first, &N, &K); struct Node lib[N]; for (int i = 0; i < N; i++) { scanf("%d %d %d", &lib[i].Address, &lib[i].Data, &lib[i].Next); lib[i].Index = 0; } int flag = first; int cnt = 0; while (flag != -1) { for (int i = 0; i < N;i++) { if(lib[i].Address==flag) { cnt++; lib[i].Index = cnt; flag = lib[i].Next; } } } struct Node Lib[cnt + 1]; for (int i = 0; i < N;i++) Lib[lib[i].Index] = lib[i]; int n = 1; while (n * K <= cnt) { int i; for (i = n * K; i > (n - 1) * K + 1; i--) printf("%05d %d %05d\n", Lib[i].Address, Lib[i].Data, Lib[i - 1].Address); if(n*K==cnt) printf("%05d %d -1\n", Lib[i].Address, Lib[i].Data); else { if ((n + 1) * K <= cnt) printf("%05d %d %05d\n", Lib[i].Address, Lib[i].Data, Lib[(n + 1) * K].Address); else { printf("%05d %d %05d\n", Lib[i].Address, Lib[i].Data, Lib[n * K + 1].Address); for (i = n * K + 1; i < cnt;i++) { printf("%05d %d %05d\n", Lib[i].Address, Lib[i].Data, Lib[i + 1].Address); } printf("%05d %d -1\n", Lib[i].Address, Lib[i].Data); } } n++; } return 0; }

    之前是使用了一个函数来直接从原数组中获取其位序,这样每次调用都需要遍历一次数组,效率较低,导致最大N的测试点一直超时,于是使用了一个新的排好序的数组来替代原数组,这样104ms通过来,有没有大佬分享一下更高效的算法?

    Processed: 0.017, SQL: 9