您的位置:首页 > 编程语言 > C语言/C++

PAT_乙级 1025 反转链表

2016-12-05 19:32 169 查看

1.题目描述:

给定一个常数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

2.解题思路:

其实这道题在C语言里用链表更不好做,应该用静态链表或者数组的思想去做这道题。没有什么特别的技巧,就是按照要求找到next指向的下一节点排好序,然后按照要求反转,反转结束之后全部改变其首尾的指针。

3.代码部分:

#include<stdio.h>
#include<string.h>

int main()
{
int a[100010][3]={0},temp[3]={0},i,j=0,staraddr,backnum,max,findaddr,count=0;
int change1[3]={0},change2[3]={0};
scanf("%d %d %d",&staraddr,&max,&backnum);
for(i=0;i<max;i++)
scanf("%d %d %d",&a[i][0],&a[i][1],&a[i][2]);
findaddr=staraddr;
for(i=0;i<max;i++)                                     //先按照顺序排好链表
{
j=i;
while(a[j][0]!=findaddr && findaddr!=-1) j++;
if(a[j][0]==findaddr)
{
memcpy(temp,&a[j],3*sizeof(int));
memcpy(&a[j],&a[i],3*sizeof(int));
memcpy(&a[i],temp,3*sizeof(int));
findaddr=a[i][2];
}
if(findaddr==-1)
{
memset(&a[i+1],0,(100001-i)*3*sizeof(int));
max=i+1;
break;
}

}
while(count+backnum<=max && max!=0)                        //按照反转要求重新排序
{
for(i=count,j=count+backnum-1;i<j;i++,j--)
{
memcpy(temp,&a[i],3*sizeof(int));
memcpy(&a[i],&a[j],3*sizeof(int));
memcpy(&a[j],temp,3*sizeof(int));
}
count+=backnum;
}
for(i=0;i<max-1;i++)						//修改反转之后链表的关系
a[i][2]=a[i+1][0];
for(i=0;i<max-1 && a[i][2]!=-1;i++)
printf("%05d %d %05d\n",a[i][0],a[i][1],a[i][2]);
printf("%05d %d -1",a[i][0],a[i][1]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C语言 PAT