给定一个常数 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 (≤105)、以及正整数 K (≤N),即要求反转的子链结点的个数。结点的地址是 5 位非负整数,NULL 地址用 −1 表示。
接下来有 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
结尾无空行
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
int a,b,c,Date[100005],Next[100005],list[100005],i;
scanf("%d%d%d",&a,&b,&c);
int temp;
for(int i=0;i<b;i++){
scanf("%d",&temp);
scanf("%d%d",&Date[temp],&Next[temp]);
}
int num=0;
while(a!=-1){//不一定所有的结点都是有用的
list[num++]=a;
a=Next[a];
}
for(i=0;i<(num-num%c);i+=c){
reverse(list+i,list+i+c);
}
i=0;
for(i=0;i<num-1;i++)printf("%05d %d %05d\n",list[i],Date[list[i]],list[i+1]);
printf("%05d %d -1",list[i],Date[list[i]]);
return 0;
}
c 的解法
#include<stdio.h>
#include<stdlib.h>
typedef struct{
int Address;
int Date;
int Next;
}Node;
int main(){
Node *node,temp;
int n,k,a,i,j;
scanf("%d%d%d",&a,&n,&k);
node=(Node*)malloc(sizeof(Node)*n);
for(i=0;i<n;i++)
scanf("%d%d%d",&node[i].Address,&node[i].Date,&node[i].Next);
for(i=0;i<n;i++)//形成有序的链表
for(j=i;j<n;j++){
if(node[j].Address==a){
temp=node[i];
node[i]=node[j];
node[j]=temp;
a=node[i].Next;
if(node[i].Next==-1){//去掉游离的结点
n=i+1;//去掉游离的结点后总的结点个数
}
break;
}
}
int roll=n/k,m;
for(i=0;i<roll;i++){//反转链表
for(j=i*k,m=0;j<k/2+i*k;j++,m++){
temp=node[j];
node[j]=node[(i+1)*k-1-m];
node[(i+1)*k-1-m]=temp;
}
}
for(i=0;i<n-1;i++){//修改地址
node[i].Next=node[i+1].Address;
}
node[i].Next=-1;
for(i=0;i<n-1;i++)
printf("%05d %d %05d\n",node[i].Address,node[i].Date,node[i].Next);
printf("%05d %d -1",node[i].Address,node[i].Date);
return 0;}