1025. 反转链表 (25)
题目
给定一个常数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 <stdio.h>
#include <stdlib.h>
typedef struct node *L;
typedef struct polynode *LL;
struct node {
int address;//当前节点模拟地址,头结点存储的是反转个数
int data;//存储数据,头结点存储的是节点总个数
int addressLink;//存储下一个结点的模拟地址,头结点存储的是第一个结点的模拟地址
L link;//真实的下一个结点的地址
};
struct polynode {
int address;
int data;
int addressLink;
};
L inputFunc();
LL find(int addressLink,struct polynode Node[],int N);
int cmp(const void *a,const void *b);
L reverseList(L listP);
L Reverse(L head,int K);
void print(L listP);
void Attach (int a,int b,int c,L *Rearp );
int main(void)
{
L listP;
listP = inputFunc();
print(reverseList(listP));
return 0;
}
L reverseList(L listP)
{
int K=listP->address;
int N=listP->data;
int i;
//第一个反转;
if(K==1)return listP;
L head=listP;
int cnt=1;
L newp,oldp,temp;
newp=head->link;
oldp=newp->link;
while(cnt<K)
{
int flag=1;
if(oldp->addressLink==-1)flag=0;
temp=oldp->link;
oldp->addressLink=newp->address;
oldp->link=newp;
newp=oldp;
if(flag)oldp=temp;
cnt++;
}
head->link->addressLink=oldp->address;
head->link->link=oldp;
head=head->link;
listP->addressLink=newp->address;
listP->link=newp;
for(i=1;i<N/K;i++)
head=Reverse(head,K);
if(N%K==0||N==K)
{
head->link=NULL;
head->addressLink=-1;
}
return listP;
}
L Reverse(L head,int K)
{
L listP=head->link;
int cnt=1;
L newp,oldp,temp;
newp=head->link;
oldp=newp->link;
while(cnt<K)
{
int flag=1;
if(oldp->addressLink==-1)flag=0;
temp=oldp->link;
oldp->addressLink=newp->address;
oldp->link=newp;
newp=oldp;
if(flag)oldp=temp;
cnt++;
}
listP->addressLink=oldp->address;
listP->link=oldp;
head->addressLink=newp->address;
head->link=newp;
return listP;
}
L inputFunc()
{
int firstAddress;
int N,i,reverseNums,count = 0;
L listP,Rear;
listP = (L)malloc(sizeof(struct node));
listP->link=NULL;
Rear=listP;
scanf("%d %d %d",&firstAddress,&N,&reverseNums);
listP->address=reverseNums;
listP->addressLink=firstAddress;
struct polynode Node[N];
for(i=0;i<N;i++)
scanf("%d %d %d",&Node[i].address,&Node[i].data,&Node[i].addressLink);
qsort(Node,N,sizeof(Node[0]),cmp);
while(Rear->addressLink!=-1)
{
LL Nnode=find(Rear->addressLink,Node,N);
count ++;
Attach(Nnode->address,Nnode->data,Nnode->addressLink,&Rear);
}
listP->data = count;
return listP;
}
LL find(int addressLink,struct polynode Node[],int N)
{
int L=0;
int R=N-1;
while(L<=R)
{
int mid=L+(R-L)/2;
if(addressLink==Node[mid].address)
return Node+mid;
else if(addressLink>Node[mid].address)
L=mid+1;
else
R=mid-1;
}
return NULL;
}
int cmp(const void *a,const void *b)
{
return (*(struct polynode *)a).address>(*(struct polynode *)b).address?1:-1;
}
void Attach (int a,int b,int c,L *Rearp )//将找到的结点添加到列表中
{
L P;
P=(L)malloc(sizeof(struct node));
P->address=a;
P->data=b;
P->addressLink=c;
(*Rearp)->link=P;
*Rearp=P;
}
void print(L listP)
{
L P = listP->link;
while(P)
{
printf("%05d %d ",P->address,P->data);
if((P->addressLink)==-1)
printf("%d",P->addressLink);
else
printf("%05d",P->addressLink);
printf("\n");
P=P->link;
}
}