1074 Reversing Linked List (25 分)思路
- 题意:第一行给出一个链表的首地址,给出结点个数N(包含有效结点和无效结点),给出一个数K,接下来N行包含每个结点的地址,结点的值,指向的下一个结点的地址。要求每隔K结点将此时的K个结点连成的链表进行一次反转,最后不到K个元素不反转。
- 思路:链表知识的应用。参考《算法笔记》
- step1:定义静态链表,由结构体结点构成,结点包含地址,结点值,next地址,顺序。
- step2:初始化,将所有结点的order都初始化为maxn,读入结点信息。
- step3:由初始地址遍历链表找出单链表所有的有效结点,在遍历的同时为其order赋值。
- step4:按order顺序对结点排序,形成最初的原始链表,接下去根据题意在此链表上进行操作即可。
- 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;
}