给定一个单链表 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是该结点保存的数据,为不超过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
和之前的链表去重有一定的区别,输出的时候别被带跑偏了,具体思路是这样的:首先先将链表都输入结构体中,然后根据循环条件
while(a[i].next!=-1){
b1[t1++]=a[i].address;
b2[t2++]=a[i].data;
i=a[i].next;
}
将排好序的链表首地址放入b1中,值放在b2中,注意这里到-1以后不循环,但是下一个地址为-1的节点还没放入数组,所以需要单独的
b1[t1++]=a[i].address;
b2[t2++]=a[i].data;
这里其实也可以用两个结构体,我这里用的是两个一维数组,是一个意思。
然后我觉得才是整个题的难点所在,怎么重排?考的时候想了半天没想出来,被前面的链表去重带跑偏了,其实不难,分析如下
while(t1--){//这里一定要用t1不能用n,因为会出现链表中有多个尾地址为-1的重复节点(无效的,无需考虑,所以t1的值是<=n的,只能用t1)
j++;//j来判断奇数偶数,如果是奇数,就输出后面的,如果是偶数,就输出前面的
if(j%2==1){
if(t1==0) printf("%05d %d -1\n",b1[max],b2[max]);//等于0时特殊考虑
else{
printf("%05d %d %05d\n",b1[max],b2[max],b1[min]);//输出后面的地址,数值和前面的地址
max--;//max--
}
}
else{
if(t1==0) printf("%05d %d -1\n",b1[min],b2[min]);
else{
printf("%05d %d %05d\n",b1[min],b2[min],b1[max]);
min++;
}
}
}
AC代码如下:
#include<iostream>
#include<string>
#include<algorithm>
#include<bits/stdc++.h>
#include<stack>
#include<set>
#include<vector>
#include<map>
#include<queue>
#include<deque>
#include<cctype>
#include<unordered_set>
#include<unordered_map>
#include<fstream>
using namespace std;
struct Node{
int address;
int data;
int next;
};
int main(){
int first,n;
cin>>first>>n;
int b1[n];
int b2[n];
Node a[100000];
for(int i=0;i<n;i++){
int address,data,next;
cin>>address>>data>>next;
a[address].address=address;
a[address].data=data;
a[address].next=next;
}
int i=first;
int t1=0,t2=0;
while(a[i].next!=-1){
b1[t1++]=a[i].address;
b2[t2++]=a[i].data;
i=a[i].next;
}
b1[t1++]=a[i].address;
b2[t2++]=a[i].data;
int j=0,min=0,max=t1-1;
while(t1--){
j++;
if(j%2==1){
if(t1==0) printf("%05d %d -1\n",b1[max],b2[max]);
else{
printf("%05d %d %05d\n",b1[max],b2[max],b1[min]);
max--;
}
}
else{
if(t1==0) printf("%05d %d -1\n",b1[min],b2[min]);
else{
printf("%05d %d %05d\n",b1[min],b2[min],b1[max]);
min++;
}
}
}
return 0;
}