给定一个单链表,请编写程序将链表元素进行分类排列,使得所有负值元素都排在非负值元素的前面,而 [0, K] 区间内的元素都排在大于 K 的元素前面。但每一类内部元素的顺序是不能改变的。例如:给定链表为 18→7→-4→0→5→-6→10→11→-2,K 为 10,则输出应该为 -4→-6→-2→7→0→5→10→18→11。
输入格式:
每个输入包含一个测试用例。每个测试用例第 1 行给出:第 1 个结点的地址;结点总个数,即正整数N (≤105);以及正整数K (≤103)。结点的地址是 5 位非负整数,NULL 地址用 −1 表示。
接下来有 N 行,每行格式为:
Address Data Next
其中 Address
是结点地址;Data
是该结点保存的数据,为 [−105,105] 区间内的整数;Next
是下一结点的地址。题目保证给出的链表不为空。
输出格式:
对每个测试用例,按链表从头到尾的顺序输出重排后的结果链表,其上每个结点占一行,格式与输入相同。
输入样例:
解释
00100 9 10 23333 10 27777 00000 0 99999 00100 18 12309 68237 -6 23333 33218 -4 00000 48652 -2 -1 99999 5 68237 27777 11 48652 12309 7 33218
输出样例:
解释
33218 -4 68237 68237 -6 48652 48652 -2 12309 12309 7 00000 00000 0 99999 99999 5 23333 23333 10 00100 00100 18 27777 27777 11 -1
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
#include <stdio.h>
struct student{
int left;
int mid;
int right;
}a[100002],b[100002],c1[100002],c2[100002],c3[100002];
int main(){
int N,K,start;
struct student *lin,t;
scanf("%d %d %d",&start,&N,&K);
int countt=0;
while(scanf("%d %d %d",&t.left,&t.mid,&t.right)!=EOF){
countt++;
lin=a+t.left;
*lin=t;
}
int count1=0,count2=0,count3=0,count=0,p=0;
if(N==1){
lin=a+start;
printf("%05d %d %d",lin->left,lin->mid,lin->right);
return 0;
}
struct student s;
for(;lin->right!=-1;){
if(count==0){
count++;
lin=a+start;
if(lin->mid<0){
c1[count1++]=*lin;
}else if(lin->mid>=0&&lin->mid<=K){
c2[count2++]=*lin;
}else if(lin->mid>K){
c3[count3++]=*lin;
}
}else{
lin=a+lin->right;
count++;
if(lin->mid<0){
c1[count1++]=*lin;
}else if(lin->mid>=0&&lin->mid<=K){
c2[count2++]=*lin;
}else if(lin->mid>K){
c3[count3++]=*lin;
}
}
}
for(int i=0;i<count1;i++){
b[p++]=c1[i];
}
for(int i=0;i<count2;i++){
b[p++]=c2[i];
}
for(int i=0;i<count3;i++){
b[p++]=c3[i];
}
for(int i=0;i<count-1;i++){
b[i].right=b[i+1].left;
}
b[count-1].right=-1;
for(int i=0;i<count-1;i++){
printf("%05d %d %05d\n",b[i].left,b[i].mid,b[i].right);
}
printf("%05d %d %d\n",b[count-1].left,b[count-1].mid,b[count-1].right);
}