菜鸡奋斗路02-线性结构3 Reversing Linked List

Given a constant K and a singly linked list L, you are supposed to reverse the links of every elements on L. For example, given L being 1→2→3→4→5→6, if K=3, then you must output 3→2→1→6→5→4; if K=4, you must output 4→3→2→1→5→6.

Input Specification:

Each input file contains one test case. For each case, the first line contains the address of the first node, a positive N (105) which is the total number of nodes, and a positive K (N) which is the length of the sublist to be reversed. The address of a node is a 5-digit nonnegative integer, and NULL is represented by -1.

Then N lines follow, each describes a node in the format:

Address Data Next

where Address is the position of the node, Data is an integer, and Next is the position of the next node.

Output Specification:

For each case, output the resulting ordered linked list. Each node occupies a line, and is printed in the same format as in the input.

Sample Input:

00100 6 4
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218

Sample Output:

00000 4 33218
33218 3 12309
12309 2 00100
00100 1 99999
99999 5 68237
68237 6 -1
作者: 陈越
单位: 浙江大学
时间限制: 400ms
内存限制: 64MB
代码长度限制: 16KB


个人分析:题目乍一看题意很清晰:输入给出一个链表L(总结点数N),要求每K个结点将链表逆序。似乎菜鸡需要做的就是:根据输入建立一个链表,然后每K个结点逆序,再将新表的表头返回,按新表输出即可。

  然而,上面一句如此简单的话,在实现过程中困难重重。

  首先,是否真的需要建立C++指针链表?由于最大测试结点数Nmax已经给出,通过结构数组链表也能达到指针链表的效果。不过,虽然指针链表的代码较复杂,但在空间复杂度方面,数组链表一定是不如指针链表节约的(测试样例结点数<

  其次,如何实现每K个结点逆序?第一想法是在遍历原链表的过程中,每经过一个结点,就将该结点逆序。然而,如果仅仅是这样,那么就会丢失下一个结点的位置,如图:

菜鸡奋斗路02-线性结构3 Reversing Linked List_第1张图片

所以,菜鸡一想,woc这不行啊...这不是要凉吗?!想想办法,想想办法.........要C点不丢.......欸?我拿个指针指着C不就行了

也就是说,在B还指着C的时候,在用一个curr指针,curr=B->Next不就行了嘛~(我怎么这么聪明?!低调低调)

  最后,还有个问题:如何返回正确的头结点?如果只用上述的3个指针可能丢失所需要的头结点,如图:

菜鸡奋斗路02-线性结构3 Reversing Linked List_第2张图片

虽然在这里好像菜鸡能在写代码之前就洞悉这些“陷阱”(都是假象= =),其实,菜鸡用了5个小时,磕磕绊绊,边写代码边debug边发现的这些问题......一把辛酸泪......不过这些都是小场面(比起在实验室做完全不动脑的体力实验,不知道好到哪去了,简直是幸福wow)

上代码!!

啊....等等!还有一个“陷阱”:陈越姥姥为了打击投机取巧凑数的同学,特别安排,初始输入的总结点数N>=链表结点数,也就是说会输入一些废结点,这些结点并不在所要处理的链表之中。所以,我们还需要在读入所有输入之后,数一下原序列到底有几个有效结点!

OjbK !!上代码!!!

#include
#define Max 100000

struct itemNode{
	int data;
	int next;
};

int Count(struct itemNode* L,int P)
{
	int cum=1;
	for(P;L[P].next!=-1;P=L[P].next)
	{
			cum++;
	}
//	printf("cum%d\n",cum);
	return cum;
}

int Reverse(struct itemNode* List,int pList,int k,int num)
{
	int prep,currp,nextp;            //prep已逆转的最后一个节点,currp未逆转的第一个节点,currp之后的第一个节点 
	int head,lasthead;              //head保存未逆序段落的旧头元素,lasthead保存逆序后的段落的尾节点 
	prep=-1;
	head=-1;
	
	currp=pList;             //使初始 
	nextp=List[currp].next;
	
	for(int i=0;i

测试结果:

菜鸡奋斗路02-线性结构3 Reversing Linked List_第3张图片


总结:这道题,让菜鸡感受到了看似简单的题目,也会有很多耐人寻味的细节!以后再写代码之前,要尽量考虑各种边界情况,这能大大缩短debug的时间(泪目....Orz...debug时头有这么大)。再者,虽然经历了5个小时的探索->失败->失败->....->失败,最后重头看整个问题,豁然开朗,菜鸡觉得很值得。最后跟大家分享debug的时候听的歌词:


Fighting!!!

你可能感兴趣的:(data,structe)