最初没有考虑到:
1、可能存在无效结点(不是从题目所给的头结点接下去的结点)
2、K个结点反转时,若是最后一组,则最后一个结点的下一结点是-1;若是倒数第二组,则要判断下一组结点个数是否刚好为K个.若<K个,则最后一个结点的下一结点为下一组结点的第一个结点地址;若=K个,则最后一个结点的下一结点为下一组结点的最后一个结点.
#include<cstdio>
#include<cstdlib>
#include<string.h>
#include<math.h>
#include<iostream>
#include<vector>
#include<set>
#include<map>
#include<string>
#include<algorithm>
using namespace std;
struct node{
int data;
int pre; //记录前驱地址
int next;
}nodes[100001];
int reverse(int first,int k){
int temp=nodes[first].next;
for(int i=2;i<k;i++){
nodes[temp].pre=first;
first=temp;
temp=nodes[temp].next;
}
nodes[temp].pre=first;
first=nodes[temp].next;
nodes[first].pre=nodes[temp].next;
printf("%05d %d %05d\n",temp,nodes[temp].data,nodes[temp].pre);
temp=nodes[temp].pre;
for(int i=1;i<k;i++){
if(i==k-1){
nodes[temp].pre=nodes[first].pre;
}
printf("%05d %d",temp,nodes[temp].data,nodes[temp].pre);
if(nodes[temp].pre==-1){
printf(" %d\n",nodes[temp].pre);
}else{
printf(" %05d\n",nodes[temp].pre);
}
temp=nodes[temp].pre;
}
return first;
}
int main(){
#ifdef ONLINE_JUDGE
#else
freopen("1.txt","r",stdin);
#endif
int first,n,k,idx;
scanf("%d %d %d",&first,&n,&k);
for(int i=0;i<n;i++){
scanf("%d",&idx);
scanf("%d %d",&nodes[idx].data,&nodes[idx].next);
}
while(n>=k){
first=reverse(first,k);
n-=k;
}
while(first!=-1){
printf("%05d %d",first,nodes[first].data);
if(nodes[first].next==-1){
printf(" %d\n",nodes[first].next);
}else{
printf(" %05d\n",nodes[first].next);
}
first=nodes[first].next;
}
return 0;
}
对上述的改进,思路:
1、定义静态链表(数组下标只是方便最开始定位结点地址,结构体中还应存储结点地址,方便之后排序结束,不丢失结点地址)
2、按照结点顺序作排序
3、作反转操作
#include<cstdio>
#include<cstdlib>
#include<string.h>
#include<math.h>
#include<iostream>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<string>
#include<algorithm>
using namespace std;
struct node{
int address,data,next;
int order; //记录结点所在序号
}nodes[100010];
bool cmp(node a,node b){
return a.order<b.order;
}
int main(){
#ifdef ONLINE_JUDGE
#else
freopen("1.txt","r",stdin);
#endif
for(int i=0;i<100010;i++){ //初始化order,方便之后排序
nodes[i].order=100010;
}
int first,n,k,count=0; //count记录有效结点个数
scanf("%d%d%d",&first,&n,&k);
for(int i=0;i<n;i++){ //初始化静态链表
int address;
scanf("%d",&address);
scanf("%d%d",&nodes[address].data,&nodes[address].next);
nodes[address].address=address;
}
while(first!=-1){ //筛选有效结点
nodes[first].order=++count;
first=nodes[first].next;
}
sort(nodes,nodes+100010,cmp);
for(int i=k-1;i<count;i+=k){
for(int j=i;j>i-k;j--){
if(j==i-k+1){ //对每组最后一个数作判断处理
printf("%05d %d ",nodes[j].address,nodes[j].data);
if(count-1-i==0){
printf("-1\n");
}else if(count-1-i<k&&count-1-i>0){
printf("%05d\n",nodes[i+1].address);
}else if(count-1-i>=k){
printf("%05d\n",nodes[i+k].address);
}
break;
}
printf("%05d %d %05d\n",nodes[j].address,nodes[j].data,nodes[j-1].address);
}
}
if(count%k!=0){ //对余数进行处理
for(int i=count/k*k;i<count;i++){
printf("%05d %d",nodes[i].address,nodes[i].data);
if(i==count-1){
printf(" -1\n");
}else{
printf(" %05d\n",nodes[i+1].address);
}
}
}
return 0;
}
反转部分算法笔记中思路更加清晰明了.