1075 链表元素分类 (25 分)【有坑,模拟链表排序,回看】

题目概述:
给定一个单链表,请编写程序将链表元素进行分类排列,使得所有负值元素都排在非负值元素的前面,而 [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注意分情况讨论;

提交结果:
提交结果

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

进击的lab681

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值