转跳点:

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 (≤)、以及正整数 K (≤),即要求反转的子链结点的个数。结点的地址是 5 位非负整数,NULL 地址用 − 表示。

接下来有 N 行,每行格式为:

  1. 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、照地址给原数组排序,记录有效数据个数
  2、对节点数进行求余、求商操作,
  3、对链表进行反转
思路是很简单,但是吧反转这里我一直没写对,好吧,刚刚终于写对了我的天,我也太菜了。
这是我写出来的的反转的代码:
  

  1. 1 for (int i = 0; i < Quotient; i++)
  2. 2 {
  3. 3 for (int j = 0; j < K / 2; j++)
  4. 4 {//因为不是和冒泡那样的连续赋值而是交换所以只要一般的的次数
  5. 5
  6. 6 //交换
  7. 7 ListNode temp = List[K * i + j];
  8. 8 List[K * i + j] = List[K * (i + 1) - j - 1];
  9. 9 List[K * (i + 1) - j - 1] = temp;
  10. 10 }
  11. 11 }

  为什么交换次数是K/2,举个栗子:1 2 3 4 5,要逆序,最暴力的方法就是从第一个数开始一个个往后移动,这无疑浪费了大量的时间在交换上,认真观察会发现,其实交换将1 和 5交换 2 和 4 就可以达到效果。奇数的时候就是中间位不用动,偶数的时候刚好对半分。所以不分奇偶。

  大佬们可以跳过下面这一段(写一个小姐姐看的)被划掉了,看不见看不见。

  那为什么是k*I+J和K * (i + 1) - j - 1交换,将I去掉后,不难发现就是将数组第一位和第K位交换,数组第二位和第K-1位上的数交换,以此类推*I是因为这是第I组刚好也相当于下标

    i = 0的时候

      0 和 k-1 换,

      1 和 k-2 换,

      ……

      k/2-1 和 k/2+1

    i = 2时      

      k 和 2k-1 换,

      k+1 和 2k-2 换,

      ……

      2k/2-1 和 2k/2+1

    ……

    i = n 时

      nk 和 2k-1 换,

      nk+1 和 nk-2 换,

      ……

      nk/2-1 和 nk/2+1

最后就是代码了:

  

  1. 1 #include <stdio.h>
  2. 2 #include <stdlib.h>
  3. 3 #define MAXSIZE 100011
  4. 4 typedef struct
  5. 5 {
  6. 6 int Address;
  7. 7 int Data;
  8. 8 int Next;
  9. 9 } ListNode;
  10. 10
  11. 11 int main(void)
  12. 12 {
  13. 13 int head, n, K;
  14. 14 ListNode List[MAXSIZE];
  15. 15 scanf("%d%d%d", &head, &n, &K);
  16. 16
  17. 17 for (int i = 0; i < n; i++)
  18. 18 {
  19. 19 scanf("%d %d %d", &List[i].Address, &List[i].Data, &List[i].Next);
  20. 20 }
  21. 21
  22. 22 //线找到首地址
  23. 23 for (int i = 0; i < n; i++)
  24. 24 {
  25. 25 if (List[i].Address == head)
  26. 26 {
  27. 27 ListNode temp = List[i];
  28. 28 List[i] = List[0];
  29. 29 List[0] = temp;
  30. 30 break;
  31. 31 }
  32. 32 }
  33. 33
  34. 34 //整理链表顺序
  35. 35 for (int i = 0; i < n; i++)
  36. 36 {
  37. 37 if (-1 == List[i].Next)
  38. 38 {
  39. 39 n = i + 1;
  40. 40 break;
  41. 41 }
  42. 42 for (int j = i + 1; j < n; j++)
  43. 43 {
  44. 44 if (List[j].Address == List[i].Next)
  45. 45 {
  46. 46 ListNode temp = List[i + 1];
  47. 47 List[i + 1] = List[j];
  48. 48 List[j] = temp;
  49. 49 break;
  50. 50 }
  51. 51 }
  52. 52 }
  53. 53
  54. 54 //取出需要交换的次数
  55. 55 int Quotient = n / K;
  56. 56
  57. 57 for (int i = 0; i < Quotient; i++)
  58. 58 {
  59. 59 for (int j = 0; j < K / 2; j++)
  60. 60 {//因为不是和冒泡那样的连续赋值而是交换所以只要一般的的次数
  61. 61
  62. 62 //交换
  63. 63 ListNode temp = List[K * i + j];
  64. 64 List[K * i + j] = List[K * (i + 1) - j - 1];
  65. 65 List[K * (i + 1) - j - 1] = temp;
  66. 66 }
  67. 67 }
  68. 68
  69. 69 //重写地址
  70. 70 for (int i = 0; i < Quotient * K; i++)
  71. 71 {
  72. 72 List[i].Next = List[i + 1].Address;
  73. 73 }
  74. 74 List[n - 1].Next = -1;
  75. 75
  76. 76
  77. 77 for (int i = 0; i < n; i++)
  78. 78 {
  79. 79 if (-1 == List[i].Next)
  80. 80 {//特殊处理-1;
  81. 81 printf("%05d %d %d\n", List[i].Address, List[i].Data, List[i].Next);
  82. 82 continue;
  83. 83 }
  84. 84 printf("%05d %d %05d\n", List[i].Address, List[i].Data, List[i].Next);
  85. 85 }
  86. 86
  87. 87 return 0;
  88. 88 }

这几组是我自己的测试数据可以拿去试试(还有一组丢了,有无效数据不能整除的)这几组数据过了之后,应该就能A了

有无效数据      能整除         不能整除

00100 10 2                      00100 10 2                         00100 10 4
0000 4 99999                  0000 4 99999                     0000 4 99999
00100 1 12309                00100 1 12309                   00100 1 12309
68237 6 -1                       68237 6 89001                   68237 6 89001
33218 3 00000                33218 3 00000                   33218 3 00000
99999 5 68237                99999 5 68237                   99999 5 68237
12309 2 33218                12309 2 33218                   12309 2 33218
89001 7 89100                89001 7 89100                   89001 7 89100
89100 8 89200                89100 8 89200                   89100 8 89200
89200 9 89300                89200 9 89300                   89200 9 89300
89300 10 89400              89300 10 -1                        89300 10 -1

  PTA不易,诸君共勉!

P 1025 链表反转的更多相关文章

  1. PAT 乙级-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,即最后 ...

  2. 链表反转leetcode206

    最近准备结束自己的科研生涯,准备要开始找工作了,准备在LEETCODE刷刷题...刷的前40题全部用python刷的,各种调包速度奇快,后被师哥告知这样没意义,于是准备开始回归C++,Python用的 ...

  3. 链表反转 (Multi-method)

    链表反转是链表相关问题最基础的知识,做完LeetCode中LinkedList后才会有这种体会,因为ACM算法中不会涉及这一部分.解决这一问题有多种方法,在面试中面试官通常也会要求写出多种.包括sta ...

  4. java实现单链表反转

    一.简介 经查阅,主要有两种方法实现链表反转,递归反转法和遍历反转法: 递归: 在反转当前结点之前先反转其后边的结点,即.从尾结点开始逆向反转各个节点的指针域指向: 遍历:从前往后反转各个结点的指针域 ...

  5. C++ 单向链表反转

    单向链表反转,一道常见的面试题,动手实现下. #include "stdafx.h" #include <stdlib.h> struct Node{ int data ...

  6. c语言:链表排序, 链表反转

    下面将实现链表排序的排序和遍历显示功能: 所定义的链表结构如下: head -> p1 -> p2 ->p3 ->....->pn; head的本身不作为数据节点,hea ...

  7. 【Java数据结构】Java数据结构之链表反转

    我们都知道用C可以很简单的实现单链表反转,今天来学习下,在Java中如何实现链表反转. 思路很简单,定义一个类,这个类分成2块,一块是表示自身的标志,另外一个存储指向下一个元素的引用.通过互换相邻两个 ...

  8. [LeetCode] 链表反转相关题目

    暂时接触到LeetCode上与链表反转相关的题目一共有3道,在这篇博文里面总结一下.首先要讲一下我一开始思考的误区:链表的反转,不是改变节点的位置,而是改变每一个节点next指针的指向. 下面直接看看 ...

  9. 单链表反转(Singly Linked Lists in Java)

    单链表反转(Singly Linked Lists in Java) 博客分类: 数据结构及算法   package dsa.linkedlist; public class Node<E> ...

随机推荐

  1. English-Names

    English-Names 1. 西方姓名的组成 2. 职业姓氏 3. 更多相关链接 中国的姓名,姓氏在前,名子在后.传统也有中间字(世代字).名子非常多.所谓百家姓,姓氏数量有限,约500个左右. ...

  2. CSP-S2019 爆炸记

    DAY -1 停课的第五天.早上来机房教练居然不在,先看了一道憨题,发现ST表+二分查找nlogn水过,然后发现单调栈可以O(n),肥肠开心 打了走人. 然后就开始颓了(逃 颓了一会之后看愤怒的小鸟这 ...

  3. java#keytool#生成私钥证书库、公钥证书库

    原文,向作者致敬

  4. JVM中 Class 文件分析

    Java 虚拟机中定义的 Class 文件格式.每一个 Class 文件都对应着唯一一个类 或接口的定义信息,但是相对地,类或接口并不一定都得定义在文件里(譬如类或接口也可以通过 类加载器直接生成). ...

  5. instance与可变参数合用,多态性

    public class Doubt { public static void main(String[] args) { Dog d1=new Dog(); Dog d2=new Zangao(); ...

  6. Day2:接着思考和可能的策划

    今天早上闹钟还没响呢,老婆就把我叫醒了~说有规律宫缩了! 7点到8点记录了一个小时,宫缩差不多5~6分钟一次! 赶紧收拾东西上医院!正好今天是40周的产检,今天还是预产期! 这孩子终于肯出来了! 结果 ...

  7. gitlab导入备份数据

    1.将南阳的gitlab 迁入到本地80虚拟机 由于本地ip地址没有固定,所以,是本地去拉取南阳的代码,虽然,之后固定了ip,但,由于只用一次这样的操作,所以,还是一直在做拉取而不是推送的工作 2.具 ...

  8. Python Sklearn.metrics 简介及应用示例

    Python Sklearn.metrics 简介及应用示例 利用Python进行各种机器学习算法的实现时,经常会用到sklearn(scikit-learn)这个模块/库. 无论利用机器学习算法进行 ...

  9. js左右选项移动

    <!--网页代码--><div class="modal" id="modal-primary7"> <div class=&qu ...

  10. SciPy 基础功能

    章节 SciPy 介绍 SciPy 安装 SciPy 基础功能 SciPy 特殊函数 SciPy k均值聚类 SciPy 常量 SciPy fftpack(傅里叶变换) SciPy 积分 SciPy ...