L2-022. 重排链表
时间限制
500 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
陈越
给定一个单链表 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
思路分析:
注意可能不是一个链表,即最后的有效结点个数不一定是n,要自己数。这个是链表中常见的陷阱,要多加注意。
重排序的时候,从num-1到num/2的序号为奇数1 3 5.... 从0到num/2-1的序号为2 4 6....
#include<iostream> #include<cstring> #include<string> #include<queue> #include<algorithm> #include<cmath> #include<vector> #include<map> #define inf 0x3f3f3f3f using namespace std; struct node { int v; int nxt; }a[100005]; struct node1 { int v; int id; int nxt; int bh; }b[100005]; map<int,int>mp; bool cmp( node1 x,node1 y) { return x.bh<y.bh; } int main() { int p=1; int h; cin>>h; a[h].v=h; int n; cin>>n; for(int i=1;i<=n;i++) { int x,v,y; cin>>x>>v>>y; a[x].v=v; a[x].nxt=y; } b[1].id=h; b[1].nxt =a[h].nxt ; b[1].v=a[h].v; int i; for(i=2;i<=n;i++) { int temp=b[i-1].nxt ; b[i].id=temp; b[i].nxt =a[temp].nxt ; b[i].v=a[temp].v; if(b[i].nxt==-1) break;//可能存在无效的 } n=i; int k=2; /*for(i=1;i<=n;i++) { cout<<b[i].bh<<" "<<b[i].id<<" "<<b[i].v<<" "<<b[i].nxt <<endl; }*/ for(i=1;i<=n/2;i++)//只要改变编号再排个序就可以了 { b[i].bh=k; k+=2; } if(n%2==0) k=k-2-1; else k=k-1; for(int i=n/2+1;i<=n;i++) { b[i].bh=k; k-=2; } /*cout<<endl<<endl; for(i=1;i<=n;i++) { cout<<b[i].bh<<" "<<b[i].id<<" "<<b[i].v<<" "<<b[i].nxt <<endl; }*/ sort(b+1,b+n+1,cmp); /*cout<<endl<<endl;*/ for(int i=2;i<=n;i++) { printf("%05d %d %05d ",b[i-1].id,b[i-1].v,b[i].id); } printf("%05d %d -1",b[n].id,b[n].v); }