7-3 重排链表 (30分)
给定一个单链表 L1 →L2 →⋯→Ln−1 →Ln ,请编写程序将链表重新排列为 Ln →L1 →Ln−1 →L2 →⋯。例如:给定L为1→2→3→4→5→6,则输出应该为6→1→5→2→4→3。
输入格式:
每个输入包含1个测试用例。每个测试用例第1行给出第1个结点的地址和结点总个数,即正整数N (≤10^5 )。结点的地址是5位非负整数,NULL地址用−1表示。
接下来有N行,每行格式为:
Address Data Next
其中Address是结点地址;Data是该结点保存的数据,为不超过10^5 的正整数;Next是下一结点的地址。题目保证给出的链表上至少有两个结点。
输出格式:
对每个测试用例,顺序输出重排后的结果链表,其上每个结点占一行,格式与输入相同。
输入样例:
00100 6
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218
输出样例:
68237 6 00100
00100 1 99999
99999 5 12309
12309 2 00000
00000 4 33218
33218 3 -1
思路:将输入的id、data、next都存下来,然后按照id以及next的地址进行排序并存入新的数组中,将数组中的数据按照要求的格式输出即可,先输出最后一个再输出第一个等等,这里输出时记得分奇数和偶数,另外还需要注意可能有多余结点,需要自己判断下排序完的数组里面结点的个数。
具体代码如下:
#include<stdio.h>
//有超时风险,可改进
struct nod
{
int id,data,next;
}a[100000],b[100000];
int main()
{
int n1,n,i,j=0, head,temp[100000];
scanf("%d%d",&head,&n);
n1=n;
for(i=0;i<n;i++)
{
scanf("%d%d%d",&a[i].id,&a[i].data,&a[i].next);
}
while(n--)
{
for(i=0;i<n1;i++)
{
if(a[i].id==head)
{
b[j].id=a[i].id;
b[j].data=a[i].data;
// b[i].next=a[i].next;
temp[j]=a[i].next;
j++;
break;
}
}
head=temp[j-1];
}
for(i=0;i<j/2;i++)
{
printf("%05d %d %05d\n",b[j-i-1].id,b[j-i-1].data,b[i].id);
if(i!=(j/2-1))
printf("%05d %d %05d\n",b[i].id,b[i].data,b[j-i-2].id) ;
else if(j%2==0)
printf("%05d %d -1\n",b[i].id,b[i].data);
else
{printf("%05d %d %05d\n",b[i].id,b[i].data,b[j-i-2].id);
printf("%05d %d -1\n",b[i+1].id,b[i+1].data);
}
}
}
测试点 提示 结果 耗时 内存
0 sample 偶数个, 地址取上下界,无多余结点 答案正确 3 ms 288 KB
1 奇数个,无多余结点 答案正确 3 ms 416 KB
2 N=2 最小case 答案正确 3 ms 416 KB
3 有多余结点 答案正确 4 ms 360 KB
4 最大N 答案正确 253 ms 3452 KB