1025. 反转链表 (25)

本文详细介绍了链表反转算法的基本原理、实现步骤,并通过具体案例演示如何使用该算法解决实际问题。其中包括输入格式解析、链表节点定义、算法核心逻辑及输出格式转换等关键环节。

1025. 反转链表 (25)

时间限制
300 ms
内存限制
32000 kB
代码长度限制
8000 B
判题程序
Standard
作者
CHEN, Yue

给定一个常数K以及一个单链表L,请编写程序将L中每K个结点反转。例如:给定L为1→2→3→4→5→6,K为3,则输出应该为3→2→1→6→5→4;如果K为4,则输出应该为4→3→2→1→5→6,即最后不到K个元素不反转。

输入格式:

每个输入包含1个测试用例。每个测试用例第1行给出第1个结点的地址、结点总个数正整数N(<= 105)、以及正整数K(<=N),即要求反转的子链结点的个数。结点的地址是5位非负整数,NULL地址用-1表示。

接下来有N行,每行格式为:

Address Data Next

其中Address是结点地址,Data是该结点保存的整数数据,Next是下一结点的地址。

输出格式:

对每个测试用例,顺序输出反转后的链表,其上每个结点占一行,格式与输入相同。

输入样例:
00100 6 4
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218
输出样例:
00000 4 33218
33218 3 12309
12309 2 00100
00100 1 99999
99999 5 68237
68237 6 -1
做这道题用了很长时间,但是最后还是有个1分的测试点没有通过,不知道漏掉哪种情况了,如果有谁知道,麻烦告诉我,感激不尽。
#include<stdio.h>
#include<malloc.h>
#define SIZE 100010
//#define SIZE 10000   //本机测试用,若用100000,太大,导致内存溢出
typedef struct Node
{
	int address;
	int data;
	int next;
}Node;


int main()
{
	Node original[SIZE];  //用节点地址的哈希表,存储节点
	Node order[SIZE];  //将节点按地址,顺序连接
	int firstAddress,totalNum,step;

	scanf("%d%d%d",&firstAddress,&totalNum,&step);
	int address, data,next;
	int i;
	for(i=0;i<SIZE;i++)
		original[i].address=-1;
	for(i=0;i<totalNum;i++)
	{
		scanf("%d%d%d",&address, &data,&next);
		original[address].address=address;
		original[address].data=data;
		original[address].next=next;
	}

	if(firstAddress==-1)
	{
		//printf("-1\n");
		return 0;
	}
	int currentAddr=firstAddress;
	for(i=0;i<totalNum;i++)
	{
		order[i]=original[currentAddr];
		currentAddr=original[currentAddr].next;
	}
	//反转输出
	int times=totalNum/step;  //反转循环次数
	int tempI=0,j;
	for(i=0;i<times;i++)
	{
		tempI=i*step;
		for(j=step-1;j>=1;j--) //当前节点的下一地址,是前一节点的地址
			printf("%05d %d %05d\n",order[tempI+j].address,order[tempI+j].data,order[tempI+j-1].address);

		//每次循环,最后一个要反转的节点,它的下一地址,有3种情况:
		//1: 该次循环后,还有一个完整的循环,即剩下的个数不小于step,此时地址是order[tempI+step*2-1].address
		//2:该次循环后,剩下的节点不能构成一个循环,只能顺序输出,此时地址是order[tempI+step].address
		//3:该节点是最后一个循环的最后一个节点

		if(tempI+step*2-1<totalNum) //1:下个循环的最后一个节点的地址
			printf("%05d %d %05d\n",order[tempI+j].address,order[tempI+j].data,order[tempI+step*2-1].address);
		else if(tempI+step<totalNum) //2:下个循环的第一个节点的地址
			printf("%05d %d %05d\n",order[tempI+j].address,order[tempI+j].data,order[tempI+step].address);
		else//3 结尾
			printf("%05d %d %d\n",order[tempI+j].address,order[tempI+j].data,-1);
	}
	i=times*step; //不是times+1
	for(;i<totalNum;i++) //不足step的,顺序输出
	{
		if(order[i].next!=-1)
			printf("%05d %d %05d\n",order[i].address,order[i].data,order[i].next);
		else
			printf("%05d %d %d\n",order[i].address,order[i].data,order[i].next);
	}
		
	return 0;
}

/*
0100 6 7
0000 4 9999
0100 1 2309
8237 6 -1
3218 3 0000
9999 5 8237
2309 2 3218
*/

/*
0100 6 4
0000 4 9999
0100 1 2309
8237 6 -1
3218 3 0000
9999 5 8237
2309 2 3218

0100 6 7
0000 4 9999
0100 1 2309
8237 6 -1
3218 3 0000
9999 5 8237
2309 2 3218

0100 6 6
0000 4 9999
0100 1 2309
8237 6 -1
3218 3 0000
9999 5 8237
2309 2 3218
*/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值