浙大版《数据结构(第2版)》题目集 --线性结构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 ^5
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.

题目大意

反转单链表,给定常数K和单链表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.

输入说明:每次输入一个案例,对每个案例,第一行内容是链表第一个节点的地址,节点数N(N<=100,000)(不一定是最终形成的单链表的节点数),常数K(<=N),K是需要反转的子链表的长度,节点的地址是一个5位的非负整数,NULL用-1来代替。
下面输入N行 格式如下:
Address Data Next
Address代表节点的位置,Data是整型数字,Next是下一个节点的位置。

解题思路

参考大神博客发现并不是链表题都必须要用链表结构去做,要多思考,先观察,逆序后不变的地方是前两组数据,即每个结点的 Address 和 data 是不变的,继续观察,其实当前结点的 next 是下一个结点的 Address
我们考虑将 Address 和 data 存起来,还要体现它们的关系,可以用数组 Data[Address] = data,同样的,我们可以将 next 和 Address 也以这种形式存储,即 Next[Address] = next
这样存储的结果是,知道 Address 我们可以通过 Data[ ] 数组找到对应 data,可以通过 Next[ ] 数组找到对应的 next
这样存储后,我们再把整个链表“理顺”,给出的 first node 即为第一个 Address,Next[first node] 是下一个结点的 Address,再用一个数组 list[ ] 把每次遇到的 Address 记录下来
到此为止我们有了能根据 Address 找到其他数据的关系数组,也有顺序记录 Address 的数组,问题就从"反转链表"简化为了"反转 Address"
再以每 K 个结点为区间,反转 list[ ] 数组中存储的 Address,再根据 Address 和其他数据的关系,就能完整地输出链表了!

代码

// 反转链表1.0.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include<iostream>
#include< iomanip>
#define MAXSIZE 100005
using namespace std;
int main()
{
	int *Data = new  int[MAXSIZE];
	int *Next = new  int[MAXSIZE];
	int *List = new  int[MAXSIZE];
	int FirstAdd, N, K;
	cin >>FirstAdd >> N >> K;
	
	for (int i = 0; i < N; i++)
	{   int tempadd, tempdata, tempnext;
		cin >> tempadd >> tempdata >> tempnext;
		Data[tempadd] = tempdata;
		Next[tempadd] = tempnext;
	}
	int sum=0;
	while (FirstAdd != -1)
	{
		List[sum++] = FirstAdd;
		FirstAdd = Next[FirstAdd];
	}
	for (int i = 0; i < sum - sum%K; i+= K)
	{
		for (int j = 0; j < K / 2; j++)
		{
			int t = List[i+j];
			List[i + j] = List[i + K - 1 - j];
			List[i + K - 1 - j] = t;

		}
	}
	for (int i = 0; i < sum - 1; i++)
	{
		printf("%05d %d% 05d\n", List[i], Data[List[i]], List[i + 1]);
	}
	cout << List[sum - 1] << " " << Data[List[sum - 1]] << " " << -1 << endl;
	return 0;
}

注意

一开始直接创建三个整形数组,每个长度为10005,结果发现出错,直接栈溢出,后来改用利用New在堆上创不会受空间限制,建数组则没有问题。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值