给定一个单链表 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 (≤105)。结点的地址是5位非负整数,NULL地址用−1表示。
接下来有N行,每行格式为:
Address Data Next
其中Address
是结点地址;Data
是该结点保存的数据,为不超过105的正整数;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>
#include <cstdio>
using namespace std;
typedef struct node{
int address;
int data;
int next;
}List;
void nodecopy(List &a,List&b){ //将a复制给b
b.address=a.address;
b.data=a.data;
b.next=a.next;
}
void rsort(List a[],List b[],int n){ //将排好序的b重排赋给a
int last=n-1,before=0,tmp=0;
for(int i=0;i<n/2;i++){
nodecopy(b[last],a[before]);
nodecopy(b[tmp],a[before+1]);
tmp++;
before+=2;
last--;
}
if(n%2){ //如果是奇数个结点,处理最后一个结点
nodecopy(b[last],a[before]);
}
for(int i=0;i<n-1;i++){ //处理重排好的链表的连接地址
a[i].next=a[i+1].address;
}
a[n-1].next=-1;
}
int main()
{
int first_address,n;
cin >> first_address>>n;
List a[n];
for(int i=0;i<n;i++){
cin >> a[i].address >> a[i].data >> a[i].next;
}
List b[n];
int Count=1;
for(int i=0;i<n;i++){ //寻找第一个结点放在b[0]
if(a[i].address==first_address){nodecopy(a[i],b[0]);}
}
while(Count < n){ //将输入的结点按顺序排好
for(int i=0;i<n;i++){
if(a[i].address==b[Count-1].next){
nodecopy(a[i],b[Count++]);
}
}
if(b[Count-1].next==-1) break; //如果next==-1,就跳出
}
rsort(a,b,Count); //重拍b赋给a
for(int i=0;i<Count;i++){ //输出链表
if(i<Count-1)
printf("%05d %d %05d\n",a[i].address,a[i].data,a[i].next);
else
printf("%05d %d %d\n",a[i].address,a[i].data,a[i].next);
}
return 0;
}