题目概述:
给定一个单链表,请编写程序将链表元素进行分类排列,使得所有负值元素都排在非负值元素的前面,而 [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 (≤
1
0
5
10^5
105);以及正整数K (≤
1
0
3
10^3
103 )。结点的地址是 5 位非负整数,NULL 地址用 −1 表示。
接下来有 N 行,每行格式为:
Address Data Next
其中 Address 是结点地址;Data 是该结点保存的数据,为 [
−
1
0
5
,
1
0
5
−10^5 ,10^5
−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
结尾无空行
代码:
#include <stdio.h>
//先B负值,然后C小于等于k的结点,最后D剩余结点
int A[100001][2]={0},B[100001][3]={0},C[100001][3]={0},D[100001][3]={0};
int main()
{
int num=0,first_address=0,value=0,temp=0,temp1=0,temp2=0,i,num_B=0,num_C=0,num_D=0,num_correct=0;
scanf("%d %d %d",&first_address,&num,&value);
for (i=0;i<num;i++)
{
scanf("%d %d %d",&temp,&temp1,&temp2);
if (temp>=0&&temp<=100000&&temp1>=-100000&&temp1<=100000&&temp2>=-1&&temp2<=100000)//排除无效数据
{
A[temp][0]=temp1;A[temp][1]=temp2;num_correct++;
}
}
for (i=0,temp=first_address;i<num_correct;i++)
{
if (A[temp][0]<0)
{
B[num_B][0]=temp;B[num_B][1]=A[temp][0];
if (num_B!=0)
B[num_B-1][2]=temp;
num_B++;
}
else if (A[temp][0]<=value)
{
C[num_C][0]=temp;C[num_C][1]=A[temp][0];
if (num_C!=0)
C[num_C-1][2]=temp;
num_C++;
}
else
{
D[num_D][0]=temp;D[num_D][1]=A[temp][0];
if (num_D!=0)
D[num_D-1][2]=temp;
num_D++;
}
temp=A[temp][1];
if (temp==-1)//防止废数据出现(测试点4)
break;
}
//填三个分类最后一行的next的地址
if (num_B!=0)
{
if (num_C!=0)
{
B[num_B-1][2]=C[0][0];
if (num_D!=0)
{
C[num_C-1][2]=D[0][0];D[num_D-1][2]=-1;
}
else
C[num_C-1][2]=-1;
}
else if(num_D!=0)
{
B[num_B-1][2]=D[0][0];D[num_D-1][2]=-1;
}
else
B[num_B-1][2]=-1;
}
else
{
if (num_C!=0&&num_D!=0)
{
C[num_C-1][2]=D[0][0];D[num_D-1][2]=-1;
}
if (num_C!=0&&num_D==0)
C[num_C-1][2]=-1;
if (num_C==0&&num_D!=0)
D[num_D-1][2]=-1;
}
for (i=0;i<num_B;i++)
{
if (B[i][2]!=-1)
printf("%05d %d %05d\n",B[i][0],B[i][1],B[i][2]);
else
printf("%05d %d -1",B[i][0],B[i][1]);
}
for (i=0;i<num_C;i++)
{
if (C[i][2]!=-1)
printf("%05d %d %05d\n",C[i][0],C[i][1],C[i][2]);
else
printf("%05d %d -1",C[i][0],C[i][1]);
}
for (i=0;i<num_D;i++)
{
if (D[i][2]!=-1)
printf("%05d %d %05d\n",D[i][0],D[i][1],D[i][2]);
else
printf("%05d %d -1",D[i][0],D[i][1]);
}
return 0;
}
Tips:
1.因为数组过大,放到主函数外开;
2.输入的时候用几个变量过渡一下;
3.输出的时候注意补0;
4.对于可能有的废数据,当查到next_address为-1时终止;
5在分类后每类最后一个结点的next_address注意分情况讨论;
提交结果: