踩过的坑:
1、可能会出现输入的数据不在链表节点上。
2、看错题目成翻转前K个元素。正确的题意:每隔k个节点翻转一下,输出翻转结果。我把翻转前K个元素的函数进行改编,写成一个独立的函数。一次又一次地输出翻转后的K个元素,直到剩余元素小于K个。我方法应该不好,只能不断地调试,直到AC。
#include <stdio.h>
#define MaxSize 100003
typedef int ElementType;
typedef int Ptr;
typedef struct node{
ElementType Data;
Ptr Next;
}Node;
int ReverseListK(Node List[],int HeadPtr,int K,int N);
void ReverseList(Node List[],int HeadPtr,int K,int N);
int main()
{
Node List[MaxSize];
int HeadPtr,N,K,NowPtr,D,NextPtr;
scanf("%d%d%d",&HeadPtr,&N,&K);
for(int i=0;i<N;i++){
scanf("%d%d%d",&NowPtr,&D,&NextPtr);
List[NowPtr].Data=D;
List[NowPtr].Next=NextPtr;
}
int tep=HeadPtr,j=0;
while(tep!=-1){
j++;
tep=List[tep].Next;
}
ReverseList(List,HeadPtr,K,j);
return 0;
}
int ReverseListK(Node List[],int HeadPtr,int K,int N)
{
int PtrList[MaxSize];
int Ptr=HeadPtr;
//记录HeadPtr开始,前K个元素的地址
for(int i=0;i<K;i++){
PtrList[i]=Ptr;
Ptr=List[Ptr].Next;
}
int Ptr2K=HeadPtr;
if(N>=2*K){
// 要在逆转前进行找第2*K个元素的地址
for(int i=0;i<2*K-1;i++)
Ptr2K=List[Ptr2K].Next;
}
int RevHeadPtr=PtrList[K-1],tep;
//逆转前K个元素
for(int i=K-1;i>0;i--){
List[PtrList[i]].Next=PtrList[i-1];
}
List[HeadPtr].Next=Ptr;
//打印逆转后的K-1个元素
tep=RevHeadPtr;
for(int i=0;i<K-1;i++){
printf("%05d %d %05d\n",tep,List[tep].Data,List[tep].Next);
tep=List[tep].Next;
}
if(List[tep].Next==-1)
printf("%05d %d %d",tep,List[tep].Data,-1);
else{
if(N>=2*K)
printf("%05d %d %05d\n",tep,List[tep].Data,Ptr2K);
else
printf("%05d %d %05d\n",tep,List[tep].Data,List[tep].Next);
}
return List[HeadPtr].Next;
}
void ReverseList(Node List[],int HeadPtr,int K,int N)
{
int PtrList[MaxSize];
int times=N/K,rest=N%K;
int tepPtr=HeadPtr;
if(N%K==0){
for(int i=0;i<times;i++){
tepPtr=ReverseListK(List,tepPtr,K,N-i*K);
}
return;
}
else{
for(int i=0;i<times;i++){
tepPtr=ReverseListK(List,tepPtr,K,N-i*K);
}
for(int i=0;i<rest-1;i++){
printf("%05d %d %05d\n",tepPtr,List[tepPtr].Data,List[tepPtr].Next);
tepPtr=List[tepPtr].Next;
}
printf("%05d %d %d",tepPtr,List[tepPtr].Data,-1);
}
}