MOOC 02-线性结构3 Reversing Linked List

MOOC 陈姥姥的数据结构作业题

Given a constant K and a singly linked list L, you are supposed to reverse the links of every K elements on L. For example, given L being 1→2→3→4→5→6, if K=3K = 3, then you must output 3→2→1→6→5→4; if K=4K = 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 NN (≤105≤10^5​​) which is the total number of nodes, and a positive KK (≤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.

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

核心:

1.用结构数组模拟链表

2.核心的逆序怎么做

我在听完陈姥姥详细的解题思路后还是困惑了一段时间,用数组下标代替指针后,具体的操作细节和边界要怎么处理;

最后我觉得给数组+1个单元作为链表的空表头,用来模拟指针链表的空表头,后面按照指针的操作具体到下标操作上,思路和步骤都会很清晰

即数组为100001个 而不是100000个

程序大概流程:

/*

1.开一个100001大小的结构数组Array,数组的下标index 就是对应结点的地址,结点中的.Next存储着链表中的下一个结点地址,即在数组中的下标。Array[0]~Array[99999]用来存储给定的数据,最后一个Array[100000] 作为整个链表的空表头,Array[100000].Next存储链表的第一个结点的数组下标

2.读入给定的数据,首地址存入Array[100000].Next,结点个数N,每次逆序的结点个数K;               之后的每行数据根据给出的下标存入对应的结构数组中:比如12309 2 33128 存入Array[12309]中 

3.由于陈姥姥挖的坑  给定的结点个数N,并不都在链表上,所以要遍历链表求得链表的实际结点数numofList;进而 得出需要逆序的次数count = numofList/K;

4.写逆序函数         

   

*/

具体看代码(c语言):

#include <stdio.h>
#define index int
#define MaxSize 100001
#define head 100000

typedef struct _Node{
	int Data;
	index Next;
}Node;

void Reverse( Node* Array,int K,int count );

int main()
{
	Node Array[MaxSize];     //连续的结构数组,其中的一部分组成链表 
	scanf("%d",&Array[head].Next);  //Array[100000]作为链表的空表头,它的.Next是链表第一个元素的数组下标
	
	int i,N,K,idx;
	scanf("%d %d",&N,&K);
	
	for(i=0;i<N;i++){     //读入数据放入对应的结构数组单元
		scanf("%d",&idx);
		scanf("%d %d",&Array[idx].Data,&Array[idx].Next);
	}
	
	int numofList=0;  //链表中实际的单元个数,不是所有读入的单元都在链表上【这里是陈姥姥挖的坑】
	index p = Array[head].Next;
	while(p!=-1){
		numofList++;
		p = Array[p].Next;
	}
	
	int count = numofList/K;  //每K个做一次逆序  需要做几次逆序
	
	Reverse( Array,K,count ); //传数组的地址进去
	
	p = Array[head].Next;  //输出  最后一个结构.Next = -1;不能直接输出-0001 需要特殊处理
	while( p != -1 ){
		if( Array[p].Next != -1 ){
			printf("%05d %d %05d\n",p,Array[p].Data,Array[p].Next);
		}else{
			printf("%05d %d %d\n",p,Array[p].Data,Array[p].Next);
		}
		p = Array[p].Next;
	}
	
	return 0;
}

void Reverse( Node* Array,int K,int count )
{
	index rear = head;//每次逆序后的尾巴 把新逆序后的链表接上 第一次是空表头 
	
	index New,Old,Temp;
	
	while(count--){
		New = Array[rear].Next;
		Old = Array[New].Next;
		
		int cnt = 1;
		
		while(cnt<K){   //逆序的核心步骤,New指向第一个 Old指向第二个 Temp临时保存Old->Next 即第三个
			Temp = Array[Old].Next;
			Array[Old].Next = New;
			New = Old;
			Old = Temp;	//每次逆序后New Old 后移1位 继续逆序 
			cnt++;
		}
		
		Temp = Array[rear].Next;           //逆序完成后的收尾工作
		Array[Array[rear].Next].Next = Old;//逆序的这一段的第一个依然还是指向第二个  需要指向后面还没有逆序的第一个
		Array[rear].Next = New;            //需要把前面尾巴指向新逆序后第一个
		rear = Temp;                       //新的 逆序后的尾巴 用来接上下次逆序后的第一个元素
	}
	
}

比第一次写的清晰很多,简洁不少,提交全红的时候还是很开心的,数据结构这门课真的很锻炼思维,前路漫漫,诸君共勉。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值