L2-2 重排链表 (25分)
给定一个单链表 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 (≤)。结点的地址是5位非负整数,NULL地址用−表示。
接下来有N行,每行格式为:
Address Data Next
其中Address是结点地址;Data是该结点保存的数据,为不超过1的正整数;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
题目分析:
这是昨天晚上天梯赛选拔赛的题目,当时读完这道题并没有做,但是事后发现这个A掉的人并不少,索性又拿出来重新看一下,绝知此事要躬行!!!
用a数组依次存储原链表的各个内存地址,b来模拟新的链表各个内存地址 本地还需注意到每个内存地址是小于1E5的 所以可以直接开数组,将其作为数组下标存储
#include <iostream>
#include <cstdio>
#include <cstring>
#define Maxn 100005
using namespace std;
struct Node {
int data,next;
}Node[Maxn];
int a[Maxn],b[Maxn];
int main(int argc,char* argv[]) {
int index,n,address;
scanf("%d %d",&index,&n);
for(int i=1; i<=n; i++) {
scanf("%d",&address);
scanf("%d %d",&Node[address].data,&Node[address].next);
}
int r = 0; a[r++] = index;
address = Node[index].next;
while(address != -1) {
a[r++] = address;
address = Node[address].next;
}
int left = 0,right = r - 1,pos = 0;
while(left <= right ) {
b[pos++] = a[right--];
if(left <= right) b[pos++] = a[left++];
}
for(int i=0; i<pos; i++) {
if(i != pos -1) printf("%05d %d %05d\n",b[i],Node[b[i]].data,b[i + 1]);
else printf("%05d %d -1",b[i],Node[b[i]].data);
}
return 0;
}