(一种更加形象的解决方法)1074 Reversing Linked List (25 分)链表逆置

提要

题目就不说了,这是一道甲乙级皆有的PAT练习题,只是语言不同。
注意点:是“每K个节点”反转一次,而不是前K个节点,本人之前一直没有理解,导致一直有两个测试点过不去…
还有就是并非每个节点都算有效,就导致有可能K>N的情况出现,需要另外处理,我相信看到我这篇的同学基本应该都知道这些。

思路

这里很多题友给出的思路是老老实实按题目反转,涉及前后替换地址啊什么的,从教程角度来说比较复杂,我根本看不懂(直球。
于是我最后想到了一种很容易理解的方法,大部分都在代码里以注释的方式说明了,这里也解释一下:
1、首先用vector存储初始顺序的链表:比如例题里给出的123456
2、把反转的部分直接用reverse函数解决(),当然这个时候只有数据是符合输出顺序的,而地址还是乱的:比如例题里给出的123456现在在vector里变成了432156,但是每个数据对应的next节点地址都是原来的,也就是错误的。
3、为了把地址搞定,直接从vector的头节点开始循环给每个节点的next地址赋值为它的下一个节点的地址即可

总而言之这样做的好处就是不用在反转的过程中不需要考虑next节点的问题,只要到后面解决即可,非常的方便,非常的美味。

#include<iostream>
#include<algorithm>
#include<vector>
#include<iomanip>
#include<cstring>
#include<math.h>
using namespace std;
struct node
{
    int address;
    int data;
    int next;
}r[100005];
int main()
{
    int A;
    int N, K;
    cin >> A >> N >> K;//按要求输入的第一行
 //下面的for是将输入的节点先保存到全局的链表数组里,为后面“按照初始顺序”插入vector作准备
    for (int i = 0; i < N; i++)
    {
        int a, k;
        int d;
        cin >> a >> d >> k;//每组的输入
        r[a] = { a,d,k };
    }
    //以下是将“有效的节点”push进vector中,以及计算实际链表长度sum
    int sum = 0;
    vector<node> s;
    for (int i = A; i != -1; i = r[i].next)
    {
        s.push_back(r[i]);
        sum++;
    }
    /*这里先不管三七二十一,把vector先按“每K个”的原则反转一次,i != s.end() - sum % K很好理解,就是这样循环到最后剩下的n个小于K,这剩余部分是不需要反转的,所以到这个n个的部分的时候就可以跳出for循环了*/
    for (auto i = s.begin();i != s.end() - sum % K; i += K)
    {
        reverse(i, i + K);
    }
    /*这样一来就很简单了,直接从头开始把当前的next值赋值为其下一个节点的地址即可,一直循环到最后一位位置,注意最后一位需要特殊处理,不解释*/
    for (int i = 0; i < s.size(); i++)
    {
        //对于最后一位,要特殊处理
        if (i == s.size() - 1)
        {
            s[i].next = -1;
            break;
        }
        s[i].next = s[i + 1].address;
    }
    //然后就是按格式输出拉,注意五位左对齐,ez
    for (int i = 0; i < s.size()-1; i++)
    {
        printf("%05d %d %05d\n", s[i].address, s[i].data, s[i].next);
    }
    printf("%05d %d %d\n", s[s.size() - 1].address, s[s.size() - 1].data, s[s.size() - 1].next);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值