(C语言版))
给定一个单链表 L 1→L 2→⋯→L n−1→L n请编写程序将链表重新排列为 L n →L 1→Ln−1→L 2→⋯。例如给定L为1→2→3→4→5→6则输出应该为6→1→5→2→4→3。输入格式每个输入包含1个测试用例。每个测试用例第1行给出第1个结点的地址和结点总个数即正整数N (≤10^5)。结点的地址是5位非负整数NULL地址用−1表示。接下来有N行每行格式为Address Data Next其中Address是结点地址Data是该结点保存的数据为不超过10^5的正整数Next是下一结点的地址。题目保证给出的链表上至少有两个结点。输出格式对每个测试用例顺序输出重排后的结果链表其上每个结点占一行格式与输入相同。输入样例0010060000049999900100112309682376-1332183000009999956823712309233218输出样例6823760010000100199999999995123091230920000000000433218332183-1#includestdlib.h#includestring.h#includestdio.htypedefstructNode{intdata;//存储数据intpre;//存储前一个节点的地址intnext;//存储下一个节点的地址}node;intmain(){node str[100005];inti,n,ID,temp;scanf(%d%d,ID,n);for(i0;in;i){intID1,num,next;scanf(%d%d%d,ID1,num,next);str[ID1].datanum;str[ID1].nextnext;//保存下一个节点的地址if(next!-1)str[next].preID1;//储存前一个节点的地址if(next-1){tempID1;//记录最后一个节点的地址}}for(;;){printf(%05d %d ,temp,str[temp].data);if(tempID){printf(-1\n);break;}elseprintf(%05d\n,ID);tempstr[temp].pre;printf(%05d %d ,ID,str[ID].data);if(IDtemp){printf(-1\n);break;}elseprintf(%05d\n,temp);IDstr[ID].next;}return0;}——————————————————————————————时隔多年再次写这道题已经看不懂原来的写法了笑死这次写出来的是下面这个版本解释过程就是对应更新第i个结点和第n-i个结点的前驱和后继信息因为它不是对称着重新排列吗。注意测试点3#includestdio.hstructnode{intpre;//记录前驱地址intdata;intnext;//记录后继地址};structnodelink[100010];intmain(){intN,n;intstart,end;//起始地址终止地址intaddress;inti,ii,j,jj;intcnt0;scanf(%d %d,start,N);for(i0;iN;i){scanf(%d,address);scanf(%d %d,link[address].data,link[address].next);}istart;//当前节点的地址j0;//记录前驱地址n0;//记录可达链表的长度while(i!-1){link[i].prej;//初始化所有前驱地址// printf(%05d %d %05d\n,link[i].pre,link[i].data,link[i].next);n;ji;ilink[i].next;if(i-1)endj;//记录可达链表的终止地址}istart;// i从左往右挪jend;// j从右往左挪cntn/2;//计算一共需要交换多少次while(cnt){link[j].nexti;// 修改j的后继地址jjlink[j].pre;// 暂存j原来的前驱地址因为j需要往左挪动link[j].prelink[i].pre;// 修改j的前驱地址link[i].prej;// 修改i的前驱地址iilink[i].next;// 暂存i的后继地址因为i需要往右挪动link[i].nextjj;// 修改i的后继地址// 这里一定是jj。// 当n为偶数个时ii与jj不相等jj是最后一个节点当n为奇数个时ii与jj相等都指向最后一个节点。if(cnt1)link[jj].next-1;iii;// i往右挪jjj;// j往左挪cnt--;}startend;//原来的最后一个节点变成了首节点所以现在的start为原来的endistart;while(i!-1){if(link[i].next-1)printf(%05d %d %d\n,i,link[i].data,link[i].next);//注意输出-1elseprintf(%05d %d %05d\n,i,link[i].data,link[i].next);ilink[i].next;}return0;}// 测试点3存在不属于链表的节点非常重要。// 输入给出的 N 个节点不一定全部属于从头节点可达的链表。所以需要遍历一遍可达链表的真实长度n。// 输入// 00001 7// 00005 50 00006// 00003 30 00004// 00001 10 00002// 00007 70 -1// 00004 40 -1// 00006 60 00007// 00002 20 00003// 输出// 00004 40 00001// 00001 10 00003// 00003 30 00002// 00002 20 -1