1025 反转链表(下标作为地址)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/LightInDarkness/article/details/82746097

给定一个常数 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 (≤10​5​​)、以及正整数 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

分析:

       说实话,这个分析也不完全是我的分析,因为我一开始看错了题目,按照我以为的来写,结果发现不对。重新看题目的时候没理解什么意思,于是就搜博客看题意。向大佬儿学习的过程中看到了用下标作为地址的方法,并且要注意内存的大小,于是采用了数组和scanf、printf的解法。

       一觉醒来再看题意总算是理解了,就是开辟一个结构体数组和vector数组(听说如果开辟int数组内存貌似会爆掉)。把数据录入结构体,地址按顺序录入vector,然后每K个节点的地址翻转过来,剩下的节点不动就好了。至于翻转的条件是什么还是自己摸索吧,光看代码应该是看不懂的。

       需要注意的是,可能会存在无效节点哦。

#include<iostream>
#include<vector>

using namespace std;

struct Node{
	int data;
	int next;
};

int main(){
	Node nodes[100000];
	int first, a, d, n, N, K;
	vector<int> addrs;
	scanf("%d %d %d", &first, &N, &K);
	for(int i = 0; i < N; i++){
		scanf("%d %d %d", &a, &d, &n);
		nodes[a].data = d;
		nodes[a].next = n;
	}
	//将地址放入vector, 无效节点被过滤掉 
	while(first != -1){
		addrs.push_back(first);
		first = nodes[first].next;
	}
	//翻转
	for(int i = 0; i < addrs.size() && addrs.size() - i + 1 >= K; i += K){
		for(int j = 0; j < K / 2 && i + K - j - 1 < addrs.size(); j++){
			int temp = addrs[i + j];
			addrs[i + j] = addrs[i + K - j - 1];
			addrs[i + K - j - 1] = temp;
		}
	}
	for(int i = 0; i < addrs.size(); i++){
		if(i != addrs.size() - 1)
			printf("%05d %d %05d\n", addrs[i], nodes[addrs[i]].data, addrs[i + 1]);
		else
			printf("%05d %d -1\n", addrs[i], nodes[addrs[i]].data);
	}
}

猜你喜欢

转载自blog.csdn.net/LightInDarkness/article/details/82746097