版权声明:本文为博主原创文章,未经博主允许不得转载。 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 (≤105)、以及正整数 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);
}
}