线性结构3 Reversing Linked List ——链表顺序存储实现

题目:

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=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 (≤10​5​​) 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

题目大概意思是:给定一个长度为N(N<=100000)的链表L,每K(K<=N)个元素进行一次反转。输入的第一行分别是链表首地址,链表长度N和数值K,后N行为链表元素的地址,存储的数据和下一位地址。

分析:由于给出了链表元素的地址和下一位地址,所以很容易联想到使用链表的顺序结构。题目的难点在于链表的顺序存储结构是使用数组实现的,即链表的前后元素是相邻的,而这里链表的前后元素是不连续的,同时链表的首地址也不是从0开始。因此,要想由顺序结构实现此链表,我们需要重新定义链表结构,增加首地址和下一位地址存储结构。通过记录当前元素的下一位地址就实现的链表的非连续连接。

链表定义:

struct Node
{
	int front;    //链表首地址
	int Data[MaxSize];    //链表数据
	int Next[MaxSize];    //下一位地址
};
typedef struct Node *List;

之后就是链表的读入,反转和输出了,其中链表反转由于是当前元素指向上一个元素,然后下一个元素再指向当前元素,因此需要记录当前元素地址,前一位地址和后一位地址,以及链表首地址,具体请看下面完整代码:

#include <stdlib.h>
#include <stdio.h>

#define NULL -1
#define MaxSize 100000

struct Node
{
	int front;
	int Data[MaxSize];
	int Next[MaxSize];
	//List Next;
};
typedef struct Node *List;

List LinkRev(List L, int N, int K);	//链表反转
void PrintLt(List L );		//链表输出

int main()
{
	int Frt, N, K;	//第一行输入
	int Cur, Dat, Nxt;	//后N行输入
	List L;
	L =(List) malloc(sizeof(struct Node));

	scanf("%d %d %d", &Frt, &N, &K);
	if(N>100000) { printf("数组超出最大值!"); return 0;}
	else L->front = Frt;	//队列的头指针

	for(int i=0; i< N; i++)
	{
		scanf("%d %d %d", &Cur, &Dat, &Nxt);
		L->Data[Cur] = Dat; L->Next[Cur] = Nxt;	//分别将数据和下一位数据地址存入队列
	}

	L = LinkRev(L ,N , K);    //链表反转

	PrintLt(L );    //链表输出

	system("pause");
	return 0;
}

List LinkRev(List L, int N, int K)	//链表反转
{
  
	int Fst, Cur, Nxt, head, rear;	//要记录初始头位置head,循环需要记录前1,当前,后1位置
	int k0,flag = 1;
	
	Nxt = L->front;

	while(N/K )
	{
	  k0 = K;
	  Cur = Nxt; Nxt = L->Next[Cur];
	  head = Cur;
  	
	  while(--k0)
	  {
  		Fst = Cur;  //前一项地址
	  	Cur = Nxt;
	  	Nxt = L->Next[Nxt]; //后一项地址
	  	L->Next[Cur] = Fst;
	  	
	  }
	  
	  if(flag ) 
	  {
		  flag = 0;
		  L->front = Cur; //当前位置赋值给表头
		  L->Next[head] = Nxt; //初始头指向下一项
		  rear = head;	//
	  }
	  else
	  {
		  L->Next[head] = Nxt; //初始头指向下一项
		  L->Next[rear] = Cur;
		  rear = head;
	  }
	  
	  N= N-K;
	}
	
	return L;
}

void PrintLt(List L)
{
	int Cur, Nxt, Dat;
	Nxt = L->front;
	
	do
	{
		Cur = Nxt; Nxt = L->Next[Cur]; Dat = L->Data[Cur];
		if(L->Next[Cur] == NULL)
			printf("%05d %d %d\n", Cur, Dat, Nxt);
		else
			printf("%05d %d %05d\n", Cur, Dat, Nxt);
	}while(L->Next[Cur] != NULL);	//如果下个数据的地址为-1则循环结束
}

代码运行之后有最后一项未通过,但是我没有理解“有多余结点不在链表上”是什么意思,因此不知该如何修改,有知道的请留言告知,感激不尽。同时,我发现如果只让循环运行一次(即只反转前K个元素),最后一项就正确了,但是第1和5就出错了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值