6-9 单链表分段逆转 (25 分)
 

给定一个带头结点的单链表和一个整数K,要求你将链表中的每K个结点做一次逆转。例如给定单链表 1→2→3→4→5→6 和 K=3,你需要将链表改造成 3→2→1→6→5→4;如果 K=4,则应该得到 4→3→2→1→5→6。

函数接口定义:

  1. void K_Reverse( List L, int K );

其中List结构定义如下:

  1. typedef struct Node *PtrToNode;
  2. struct Node {
  3. ElementType Data; /* 存储结点数据 */
  4. PtrToNode Next; /* 指向下一个结点的指针 */
  5. };
  6. typedef PtrToNode List; /* 定义单链表类型 */

L是给定的带头结点的单链表,K是每段的长度。函数K_Reverse应将L中的结点按要求分段逆转。

裁判测试程序样例:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. typedef int ElementType;
  4. typedef struct Node *PtrToNode;
  5. struct Node {
  6. ElementType Data; /* 存储结点数据 */
  7. PtrToNode Next; /* 指向下一个结点的指针 */
  8. };
  9. typedef PtrToNode List; /* 定义单链表类型 */
  10. List ReadInput(); /* 裁判实现,细节不表 */
  11. void PrintList( List L ); /* 裁判实现,细节不表 */
  12. void K_Reverse( List L, int K );
  13. int main()
  14. {
  15. List L;
  16. int K;
  17. L = ReadInput();
  18. scanf("%d", &K);
  19. K_Reverse( L, K );
  20. PrintList( L );
  21. return 0;
  22. }
  23. /* 你的代码将被嵌在这里 */

输入样例:

  1. 6
  2. 1 2 3 4 5 6
  3. 4

输出样例:

  1. 4 3 2 1 5 6

  1. 1 void K_Reverse( List L, int K ){
  2. 2 PtrToNode r, p, end1,end2 ,H = L->Next;//_ 1 2 3 4 5 6 7 8 9 10 11 12
  3. 3 /**end1和end2是用来连接两个逆置后的分段;
  4. 4 一开始我们令end1指向头节点,end2指向数据1所在的节点,为什么这样做呢?
  5. 5 因为前四个数据我们都要把他以头插入方式插到L后面,也就是end1后面;
  6. 6 当我们遍历到节点5的时候我们需要令end1 = end2;end2 = 5所在的节点;
  7. 7 然后我们需要将5 6 7 8再以头插入的方式插入到1节点的后面,也就是end1的后面
  8. 8 也就是说我们一直将节点以头插入的方式插入到end1后面,而end2使用来记录下一个
  9. 9 分段的第一个节点,也就是下一个end1,就这样不断更新end1就可以实现将整个链表
  10. 10 分段逆置;这是end1和end2的作用
  11. 11 */
  12. 12 end1 = L;
  13. 13 end2 = L->Next;
  14. 14 r = L->Next; //用来遍历链表
  15. 15 p = r->Next;
  16. 16 int count = 0;
  17. 17 /**
  18. 18 count用来记录链表节点总数;
  19. 19 为什么要记录总数?
  20. 20 因为我们要知道链表最后一个分段是不足K个节点,还是刚好K个节点;
  21. 21 如果不足就不用逆置,如果刚好也要把这一分段逆置了;
  22. 22 */
  23. 23 if (K>=1) //这里就是我上面说的考虑K的情况
  24. 24 {
  25. 25 //记录总数
  26. 26 while (H)
  27. 27 {
  28. 28 count++;
  29. 29 H = H->Next;
  30. 30 }
  31. 31
  32. 32 //判断,如果总数小于K就不变链表
  33. 33 if (count>=K)
  34. 34 {
  35. 35 /**count/K是我们总共需要循环几个分段,因为count/K结果去商,
  36. 36 所以如果count不能被K整除,即最后一个分段不足K个,我们就不循环
  37. 37 也就是不动它。
  38. 38 */
  39. 39 for (int j = 0;j<count/K;j++)
  40. 40 {
  41. 41 //每个分段循环K次
  42. 42 for(int i = 0; i < K; i++)
  43. 43 {
  44. 44 r->Next = end1->Next; //头插入
  45. 45 end1->Next = r;
  46. 46 r = p;
  47. 47 /**
  48. 48 这里为什么要判断p不为空呢?
  49. 49 因为我一开令r = L->Next;
  50. 50 p = r->Next;
  51. 51 所以最后p会指向链表最后的Next域,而Next为空,就不
  52. 52 存在p的Next域,如果不判断的话程序运行到此处就不会再运行下去
  53. 53 而程序一开始编译的时候不会报错,所以这一点很重要,即判断越界
  54. 54 问题,我也是找了很长时间才找点这一点。
  55. 55 */
  56. 56 if(p)
  57. 57 p = p->Next;
  58. 58 }
  59. 59 end1 = end2; //更新end1和end2
  60. 60 end2 = r;
  61. 61 }
  62. 62 end1->Next = r; //最后将尾节点Next域置空。
  63. 63 }
  64. 64 }
  65. 65
  66. 66 }

PTA 单链表分段逆转的更多相关文章

  1. 数据结构1_C---单链表的逆转

    通过C语言函数实现单链表的逆转操作 例: 输入数据1,2,3,4 输出数据4,3,2,1 一共三个文件: 头文件stulist,h :链表结点的定义,结点指针的定义 源文件stulist.c:具体的实 ...

  2. PTA 6-1 单链表逆转

    本题是一个非常经典的题目:单链表逆转. 这是链表结点的定义: typedef struct Node *PtrToNode; struct Node { ElementType Data; /* 存储 ...

  3. LeetCode 笔记系列六 Reverse Nodes in k-Group [学习如何逆转一个单链表]

    题目:Given a linked list, reverse the nodes of a linked list k at a time and return its modified list. ...

  4. Python3玩转单链表——逆转单向链表pythonic版

    [本文出自天外归云的博客园] 链表是由节点构成的,一个指针代表一个方向,如果一个构成链表的节点都只包含一个指针,那么这个链表就是单向链表. 单向链表中的节点不光有代表方向的指针变量,也有值变量.所以我 ...

  5. 6. Reverse Linked List 逆转单链表

    逆转单链表,比较简单,不细讲,扫描依次改变指针指向. class Solution { public: ListNode* reverseList(ListNode* head) { if(head= ...

  6. PTA 循环单链表区间删除 (15 分)

    本题要求实现带头结点的循环单链表的创建和单链表的区间删除.L是一个带头结点的循环单链表,函数ListCreate_CL用于创建一个循环单链表,函数ListDelete_CL用于删除取值大于min小于m ...

  7. 数据结构 单链表元素定位 PTA

    由于这个很简单,他也貌似没要判断溢出,取巧突破 #include<stdio.h> #include<malloc.h> #include<stdlib.h> // ...

  8. PTA之求单链表结点的阶乘和

    本题要求实现一个函数,求单链表L结点的阶乘和.这里默认所有结点的值非负,且题目保证结果在int范围内. 时间限制: 400ms 内存限制: 64MB 代码长度限制: 16KB 函数接口定义: int ...

  9. pta 奇数值结点链表&&单链表结点删除

    本题要求实现两个函数,分别将读入的数据存储为单链表.将链表中奇数值的结点重新组成一个新的链表.链表结点定义如下: struct ListNode { int data; ListNode *next; ...

随机推荐

  1. Dapr 交通控制示例

    Dapr 已在塔架就位 将发射新一代微服务 牛年 dotnet云原生技术趋势 Dapr是如何简化微服务的开发和部署 前面几篇文章都是从大的方面给大家分享Dapr 能帮助我们解决什么问题,微软从开源到1 ...

  2. 深入理解JavaScript中的类继承

    由于写本文时全部是在编辑器中边写代码边写感想的,所以,全部思想都写在代码注释里面了 // 类继承 //todo.1 extends 关键字 class Animal { constructor(nam ...

  3. μC/OS-III---I笔记1---概述

    在裸板上跑一些程序对于一些电子设计是足够的,所谓裸板上的程序就是传统的前后台系统,而我的理解它应该是一种"过程类"的程序,一个大循环(作为后台)做一些处理,中断程序(作为前台)来处 ...

  4. 记一次FreeRTOS错误配置导致无法进入临界区

    最近项目用到FreeRTOS,在实际调试中发现我自己的一段代码本来好用的(在无RTOS的情况下),但是当我在带RTOS的情况下把代码放到一个单独的任务中运行时我发现本来好用的代码莫名其妙的出现问题,有 ...

  5. js & touch & pull down & load more

    js & touch & pull down & load more https://www.jianshu.com/p/93597d6bd77d index-list htt ...

  6. axios upload excel file

    axios upload excel file https://github.com/axios/axios/issues/1660 https://stackoverflow.com/questio ...

  7. js destructuring assignment bug

    js destructuring assignment bug https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Op ...

  8. URLSearchParams & GET Query String & JSON

    URLSearchParams & GET Query String & JSON https://developer.mozilla.org/zh-CN/docs/Web/API/U ...

  9. 算法型稳定币USDN有什么魔力引发市场热潮?

    最近比特币重新突破了8万大关,区块链行业又再次火爆起来,吸引了圈内圈外人的火热讨论,而这其中市场投资者讨论最频繁的就要属算法型稳定币USDN了. USDN是基于NGK.IO区块链中的稳定币, 1枚US ...

  10. NGK Baccarat流动性挖矿打造DeFi新风口

    2020年,DEFI成为了区块链领域最热门的概念之一.它就像乐高积木,将原来的金融模块,以不同的智能合约来实现.智能合约又以全新的方式将不同的金融功能拼接在一起,以创造出全新的金融产品. NGK.IO ...