• 1025 反转链表


    一.问题: 

            给定一个常数 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 是下一结点的地址。

    输出格式:

            对每个测试用例,顺序输出反转后的链表,其上每个结点占一行,格式与输入相同。

    输入样例:

    1. 00100 6 4
    2. 00000 4 99999
    3. 00100 1 12309
    4. 68237 6 -1
    5. 33218 3 00000
    6. 99999 5 68237
    7. 12309 2 33218

    输出样例:

    1. 00000 4 33218
    2. 33218 3 12309
    3. 12309 2 00100
    4. 00100 1 99999
    5. 99999 5 68237
    6. 68237 6 -1

    二.思路:

            这题关键是把链表结点正确链接起来,也就是用数组正确将结点按顺序存储,然后才能继续实现反转链表,这里可以把结点的地址作为数组下标,将结点存储在数组里面,后面排序会很方便。

            接下来就是要注意,在反转完后的链表,最后一个节点指向-1,这里要注意!具体看代码:

    三.代码实现:

    1. #include
    2. //定义链表结构
    3. typedef struct Link{
    4. int Address;//结点地址
    5. int Data;//该结点保存的整数数据
    6. int Next;//下一结点的地址
    7. } Link;
    8. int main()
    9. {
    10. //输入数据,并把链表排好顺序
    11. int first;//第 1 个结点的地址
    12. int N;//结点总个数正整数 N
    13. int K;//要求反转的子链结点的个数
    14. scanf("%d %d %d",&first,&N,&K);
    15. //定义两个链表结点数组
    16. Link node1[100000];//用于存储初始排好的顺序链表结点
    17. Link node2[100000];//用于存储完成反转后的链表结点
    18. //定义临时结点变量,临时存储输入的每个节点数据
    19. Link t_node;
    20. for(int i =0;i < N;i++)
    21. {
    22. scanf("%d %d %d",&t_node.Address,&t_node.Data,&t_node.Next);
    23. node1[t_node.Address] = t_node;//这里将结点当前地址作为数组元素下标,为了下面排序结点用,多体会这一步
    24. }
    25. //将链表结点排序,这里的排序方法很巧妙,多思考
    26. int start = 0;
    27. for(int j = first;j != -1;j = node1[j].Next)
    28. {
    29. node2[start] = node1[j];
    30. start++;
    31. }
    32. //输出翻转后的链表
    33. int T = start / K;
    34. int t = 0;
    35. for(;t < T;t++)
    36. {
    37. int k = t*K+K-1;
    38. for(;k > t*K;k--)
    39. {
    40. printf("%05d %d %05d\n",node2[k].Address,node2[k].Data,node2[k-1].Address);
    41. }
    42. //此时k指向第t组的第一个元素
    43. if(t != T-1)
    44. {
    45. int next1 = (t+1)*K+K-1;
    46. printf("%05d %d %05d\n",node2[k].Address,node2[k].Data,node2[next1].Address);
    47. }
    48. else
    49. {
    50. if(start % K == 0)
    51. {
    52. printf("%05d %d -1\n",node2[k].Address,node2[k].Data);
    53. }
    54. else
    55. {
    56. int next2 = (t+1)*K;
    57. printf("%05d %d %05d\n",node2[k].Address,node2[k].Data,node2[next2].Address);
    58. }
    59. }
    60. }
    61. //输出翻转后剩余不能翻转的链表
    62. for(int m = t*K;m < start;m++)
    63. {
    64. if(m != start-1)
    65. {
    66. printf("%05d %d %05d\n",node2[m].Address,node2[m].Data,node2[m].Next);
    67. }
    68. else
    69. {
    70. printf("%05d %d -1\n",node2[m].Address,node2[m].Data);
    71. }
    72. }
    73. return 0;
    74. }

  • 相关阅读:
    Linux内存管理 | 四、物理地址空间设计模型
    2022/11/27一周总结
    asp.net core之中间件
    每日实用技巧分享:怎么修复老照片?
    超火的低代码平台长什么样
    Vue computed/watch原理
    【若依框架RuoYi-Vue-Plus 图片回显不显示问题,OSS文件上传或者本地上传】
    【C++】·搭建HTTP服务器
    java EE初阶 — 如何进行多线程编程
    在大数据相关技术中,HBase是个分布的、面向列的开源数据库,是一个适合于非结构化数据存储的数据库。
  • 原文地址:https://blog.csdn.net/2303_76295261/article/details/133556907