给定一个单链表 L1→L2→⋯→Ln−1→Ln,请编写程序将链表重新排列为 LnL1→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行,每行格式为:

1
Address Data Next

其中Address是结点地址;Data是该结点保存的数据,为不超过105的正整数;Next是下一结点的地址。题目保证给出的链表上至少有两个结点。

输出格式:

对每个测试用例,顺序输出重排后的结果链表,其上每个结点占一行,格式与输入相同。

输入样例 :

1
2
3
4
5
6
7
00100 6
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218

输出样例 :

1
2
3
4
5
6
68237 6 00100
00100 1 99999
99999 5 12309
12309 2 00000
00000 4 33218
33218 3 -1

思路:

静态链表求解。用结构体数组模拟链表,先遍历一遍链表,把在链表上的结点存起来,防止有不在链表中的干扰数据。然后从后往前交替输出,l, r代表将要输出的节点位置,当r出现在l左侧时说明都遍历一遍,可退出循环。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include<bits/stdc++.h>
using namespace std;
struct node{
int address,data,next;
}Poly[100005];
vector<node> v,ans;
int main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int start,N,address;
cin >> start >> N;
for(int i=0;i<N;i++){
cin >> address;
Poly[address].address = address;
cin >> Poly[address].data >> Poly[address].next;
}
while(start!=-1){
v.push_back(Poly[start]);
start = Poly[start].next;
}
int l=0,r=v.size()-1;
while(1){
ans.push_back(v[r]);
r--;
if(r<l) break;
ans.push_back(v[l]);
l++;
if(r<l) break;
}
for(int i=0;i<ans.size();i++){
if(i!=ans.size()-1) printf("%05d %d %05d\n",ans[i].address,ans[i].data,ans[i+1].address);
else printf("%05d %d -1\n",ans[i].address,ans[i].data);
}
return 0;
}