题目描述:
给定一个单链表 L 1 →L 2 →⋯→L n−1 →L n ,请编写程序将链表重新排列为 L n →L 1 →L n−1 →L 2 →⋯。例如:给定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
代码如下:
#include<iostream>
using namespace std;
struct node
{
int addr,data,next;
}li[100000];
int main()
{
int a,n,ad;
scanf("%d%d",&a,&n);
node m[100000];
for(int i=0;i<n;i++){
scanf("%d",&ad);
scanf("%d%d",&li[ad].data,&li[ad].next);
li[ad].addr=ad;
m[li[ad].data].addr=ad;
}
int cnt[n+1]={0},temp,ex[n+1]={0},flag=0,ma;
for(ma=0;a!=-1;ma++){
cnt[ma]=li[a].data;
a=li[a].next;
}
for(int i=0,j=ma-1,k=0;i<=j;k++){
if(!flag){
ex[k]=cnt[j--];
flag=1;
}
else {
ex[k]=cnt[i++];
flag=0;
}
}
for(int i=0;i<ma;i++){
if(i==0) printf("%05d %d ",m[ex[i]].addr,ex[i]);
else printf("%05d\n%05d %d ",m[ex[i]].addr,m[ex[i]].addr,ex[i]);
}
printf("-1");
return 0;
}
来总结一下:
1)类似这样的题,用结构体来表示节点信息的话会更加的方便。
2)结构体定义了两个数组,li[]数组是以结点的地址为下标,m[]数组是以结点的数据data为下标,(m[]数组中只需要记录其地址即可)前者方便换成链式,后者方便换完之后输出。
3)先把他们的数据换好后,再按照m[]数组输出。
4)我输出的结构是两个一组,一个是其地址,一个是其数据,最后输出-1。