给定一个常数 K 以及一个单链表 L,请编写程序将 L 中每 K 个结点反转。例如:给定 L 为 1→2→3→4→5→6,K 为 3,则输出应该为 3→2→1→6→5→4;如果 K 为 4,则输出应该为 4→3→2→1→5→6,即最后不到 K 个元素不反转。
输入格式:
每个输入包含 1 个测试用例。每个测试用例第 1 行给出第 1 个结点的地址、结点总个数正整数 N (≤105)、以及正整数 K (≤N),即要求反转的子链结点的个数。结点的地址是 5 位非负整数,NULL 地址用 −1 表示。
接下来有 N 行,每行格式为:
Address Data Next
其中 Address 是结点地址,Data 是该结点保存的整数数据,Next 是下一结点的地址。
输出格式:
对每个测试用例,顺序输出反转后的链表,其上每个结点占一行,格式与输入相同。
输入样例:
- 00100 6 4
- 00000 4 99999
- 00100 1 12309
- 68237 6 -1
- 33218 3 00000
- 99999 5 68237
- 12309 2 33218
输出样例:
- 00000 4 33218
- 33218 3 12309
- 12309 2 00100
- 00100 1 99999
- 99999 5 68237
- 68237 6 -1
这题关键是把链表结点正确链接起来,也就是用数组正确将结点按顺序存储,然后才能继续实现反转链表,这里可以把结点的地址作为数组下标,将结点存储在数组里面,后面排序会很方便。
接下来就是要注意,在反转完后的链表,最后一个节点指向-1,这里要注意!具体看代码:
- #include
- //定义链表结构
- typedef struct Link{
- int Address;//结点地址
- int Data;//该结点保存的整数数据
- int Next;//下一结点的地址
- } Link;
- int main()
- {
- //输入数据,并把链表排好顺序
- int first;//第 1 个结点的地址
- int N;//结点总个数正整数 N
- int K;//要求反转的子链结点的个数
-
- scanf("%d %d %d",&first,&N,&K);
-
- //定义两个链表结点数组
- Link node1[100000];//用于存储初始排好的顺序链表结点
- Link node2[100000];//用于存储完成反转后的链表结点
-
- //定义临时结点变量,临时存储输入的每个节点数据
- Link t_node;
- for(int i =0;i < N;i++)
- {
- scanf("%d %d %d",&t_node.Address,&t_node.Data,&t_node.Next);
- node1[t_node.Address] = t_node;//这里将结点当前地址作为数组元素下标,为了下面排序结点用,多体会这一步
- }
-
- //将链表结点排序,这里的排序方法很巧妙,多思考
- int start = 0;
- for(int j = first;j != -1;j = node1[j].Next)
- {
- node2[start] = node1[j];
- start++;
- }
- //输出翻转后的链表
- int T = start / K;
- int t = 0;
- for(;t < T;t++)
- {
- int k = t*K+K-1;
- for(;k > t*K;k--)
- {
- printf("%05d %d %05d\n",node2[k].Address,node2[k].Data,node2[k-1].Address);
- }
- //此时k指向第t组的第一个元素
- if(t != T-1)
- {
- int next1 = (t+1)*K+K-1;
- printf("%05d %d %05d\n",node2[k].Address,node2[k].Data,node2[next1].Address);
- }
- else
- {
- if(start % K == 0)
- {
- printf("%05d %d -1\n",node2[k].Address,node2[k].Data);
- }
- else
- {
- int next2 = (t+1)*K;
- printf("%05d %d %05d\n",node2[k].Address,node2[k].Data,node2[next2].Address);
- }
- }
-
- }
-
- //输出翻转后剩余不能翻转的链表
- for(int m = t*K;m < start;m++)
- {
- if(m != start-1)
- {
- printf("%05d %d %05d\n",node2[m].Address,node2[m].Data,node2[m].Next);
- }
- else
- {
- printf("%05d %d -1\n",node2[m].Address,node2[m].Data);
- }
- }
- return 0;
- }