给定一个单链表 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
分析:
采用和上次一样的办法,用pair<int,int> 来存;
先把链表正确顺序的地址存储下来,然后根据题目要求,采用双指针将地址重排。
最后再将重排后的地址写回到原结点中;
需要的注意的是,给出的结点有可能是孤立结点,就是不在链表中的结点,题给的结点数量不能直接使用,可以自己统计。
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<unordered_map>
#define x first
#define y second
#define _for(i,s,t) for(int i = (s);i <=t ; i++)
#define FAST ios::sync_with_stdio(false); cin.tie(0);cout.tie(0);
using namespace std;
typedef unsigned long long ULL;
typedef long long LL;
typedef pair<int,int> PII;
const int N = 100010,INF = 0x3f3f3f3f;
PII node[N];
int fs,n,cfs;
int ad[N],tmp[N],idx,tidx;
int main()
{
scanf("%d%d",&fs,&n);
for(int i = 0 ;i < n ;i ++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
node[a] = {b,c};
}
for(int i = fs ;i != -1 ;i = node[i].y) ad[idx++] = i;
for(int i = 0,j = idx - 1;j >= i; j--,i++)
{
tmp[tidx++] = ad[j];
tmp[tidx++] = ad[i];
}
cfs = tmp[0];
int cp = cfs;
for(int i = 1 ;i < idx ;i ++)
{
auto t = node[cp];
node[cp].y = {tmp[i]};
cp = tmp[i];
}
node[cp].y = -1;
for(int i = cfs; i != -1 ; i = node[i].y)
{
if(node[i].y >= 0) printf("%05d %d %05d\n",i,node[i].x,node[i].y);
else printf("%05d %d %d\n",i,node[i].x,node[i].y);
}
return 0;
}