转跳点:

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 行,每行格式为:

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

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

    导入 matplotlib 模块: import matplotlib 查看自己版本所支持的backends: print(matplotlib.rcsetup.all_backends) 返回信息: ...

  2. ORACLE锁表问题

    1.查询锁表的信息 select sess.sid,sess.serial#, lo.oracle_username,lo.os_user_name, ao.object_name,lo.locked ...

  3. JS原生编写实现留言板功能

    实现这个留言板功能比较简单,所以先上效果图: 实现用户留言内容,留言具体时间. <script> window.onload = function(){ var oMessageBox = ...

  4. 常用命令提示符(cmd)

    MS-DOS(Microsoft Disk Operation System)命令提示符(cmd) 启动: win+ R 输入cmd回车切换盘符   盘符名称:进入文件夹   cd 文件夹名称进入多级 ...

  5. MySQL序列解决方案

    MySQL序列解决方案 MySQLOracleSQL  MySQL自增长与Oracle序列的区别: 自增长只能用于表中的其中一个字段 自增长只能被分配给固定表的固定的某一字段,不能被多个表共用. 自增 ...

  6. Python集合语法

    a = {1,2,3,4,5,6,7,8,"aa","2"}    b = {2,3,4,5,6,7,8,9,99,7,6,6} v = a.intersect ...

  7. Lesson 45 Of men and galaxies

    In man's early days, competition with other creatures must have been critical. But this phase of our ...

  8. 怎样快速高效的定义Django的序列化器

    1.使用Serializer方法自己创建一个序列化器 先写一个简单的例子 class BookInfoSerializer(serializers.Serializer): ""& ...

  9. 2.12 学习总结 之 表单校验插件validate

    一.说在前面 昨天 学习了ajax的相关知识 今天 学习表单校验插件validate, 并使用ajax 自定义校验规则 二.validate 插件 1.网络上有许多成熟的插件共使用者参考,插件就是将j ...

  10. ThinkPad重大更新!5款创意设计PC齐发2日

    导读 日前,ThinkPad巨匠P系列专业移动工作站迎来全线更新,包括ThinkPad P1隐士2019.ThinkPad P53.ThinkPad P73.ThinkPad P43s.ThinkPa ...