2021-03-04PAT甲级1074 Reversing Linked List (25 分)思路

1074 Reversing Linked List (25 分)思路

  1. 题意:第一行给出一个链表的首地址,给出结点个数N(包含有效结点和无效结点),给出一个数K,接下来N行包含每个结点的地址,结点的值,指向的下一个结点的地址。要求每隔K结点将此时的K个结点连成的链表进行一次反转,最后不到K个元素不反转。
  2. 思路:链表知识的应用。参考《算法笔记》
  3. step1:定义静态链表,由结构体结点构成,结点包含地址,结点值,next地址,顺序。
  4. step2:初始化,将所有结点的order都初始化为maxn,读入结点信息。
  5. step3:由初始地址遍历链表找出单链表所有的有效结点,在遍历的同时为其order赋值。
  6. step4:按order顺序对结点排序,形成最初的原始链表,接下去根据题意在此链表上进行操作即可。
  7. step5:输出链表(这一步模拟起来逻辑比较繁琐):–>如果i号块不是最后一个完整块,那么next就是(i+2)*K-1号结点,也就是(i+1)号块的最后一个节点。–>如果i号块是最后一个完整块,同样分为两种情况:------n%K为0,即这是单链表的最后一个结点,输出-1,如果n%K不为0,说明这个完整块后面还有一点“尾巴”,这个完整块最后一个结点的next是(i+1)*K号结点,即尾巴的第一个结点,接下去,从前往后输出尾巴的所有结点。
    算法思路主要参考的《算法笔记》,代码如下:
#include<bits/stdc++.h>
using namespace std;
const int maxn=100010;
struct Node
{
    int address,data,next;
    int order;
}node[maxn];
bool cmp(Node a,Node b)
{
    return a.order<b.order;
}
int main()
{
    for(int i=0;i<maxn;i++)
    {
        node[i].order=maxn;
    }
    int begin,n,K,address;
    scanf("%d%d%d",&begin,&n,&K);
    for(int i=0;i<n;i++)
    {
        scanf("%d",&address);
        scanf("%d%d",&node[address].data,&node[address].next);
        node[address].address=address;
    }
    int p=begin,count=0;
    while(p!=-1)
    {
        node[p].order=count++;
        p=node[p].next;
    }
    sort(node,node+maxn,cmp);
    n=count;
    for(int i=0;i<n/K;i++)
    {
        for(int j=(i+1)*K-1;j>i*K;j--)
        {
            printf("%05d %d %05d\n",node[j].address,node[j].data,node[j-1].address);
        }
        printf("%05d %d ",node[i*K].address,node[i*K].data);
        if(i<n/K-1)
        {
            printf("%05d\n",node[(i+2)*K-1].address);
        }
        else
        {
            if(n%K==0)
                printf("-1\n");
            else
            {
                printf("%05d\n",node[(i+1)*K].address);
                for(int i=n/K*K;i<n;i++)
                {
                    printf("%05d %d ",node[i].address,node[i].data);
                    if(i<n-1)
                        printf("%05d\n",node[i+1].address);
                    else
                        printf("-1\n");
                }
            }
        }
    }
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值