给定一个常数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
0 0网上的方法终归是他人的办法,可以参考,想用自己的方法解。但是错了好多次,还是解不出来,有没有大牛帮帮忙
#include<iostream>
#include<string>
#include<algorithm>
#define N 11000
using namespace std;
struct Node {
string Posistion;
string NextPosistion;
int sign;//标记,翻转使用sort函数实现
int Data;
}Lnode[N], testLnode[N];//初始链表,有效链表
bool cmp(Node a, Node b) {
return a.sign>b.sign;
}
int main() {
string firstPosition;//首地址
int n, K;
cin >> firstPosition >> n >> K;
//输入参数
for (int i = 0; i < n; i++) {
cin >> Lnode[i].Posistion >> Lnode[i].Data >> Lnode[i].NextPosistion;
}
//判断首地址是否为空
if (firstPosition != "-1") {
//排序
int x = 0;//记录有效链表
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {//将有效链表记录并标记排序
if (Lnode[j].Posistion == firstPosition) {
firstPosition = Lnode[j].NextPosistion;
Lnode[j].sign = x;
testLnode[x++] = Lnode[j];
break;
}
}
}
//判断后面是否需要翻转
if (x - K >= K) {
sort(testLnode, testLnode + K, cmp);
sort(testLnode + K, testLnode + x, cmp);
}
else
sort(testLnode, testLnode + K, cmp);
//将下个地址的首地址赋值给上个地址的下个地址
for (int i = 0; i < x - 1; i++) {
testLnode[i].NextPosistion = testLnode[i + 1].Posistion;
}
//将最后一位的下个地址赋值为空
testLnode[x - 1].NextPosistion = "-1";
//遍历输出
for (int i = 0; i < x; i++)
cout << testLnode[i].Posistion << " " << testLnode[i].Data << " " << testLnode[i].NextPosistion << endl;
}
else{
cout << "-1" << endl;
}
return 0;
}
最后附上大佬的正解:@柳婼
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int first, k, n, temp;
cin >> first >> n >> k;
int data[100005], next[100005], list[100005];
for (int i = 0; i < n; i++) {
cin >> temp;
cin > > data[temp] >> next[temp];
}
int sum = 0;//不一定所有的输入的结点都是有用的,加个计数器
while (first != -1) {
list[sum++] = first;
first = next[first];
}
for (int i = 0; i < (sum - sum % k); i += k)
reverse(begin(list) + i, begin(list) + i + k);
for (int i = 0; i < sum - 1; i++)
printf("%05d %d %05d\n", list[i], data[list[i]], list[i + 1]);
printf("%05d %d -1", list[sum - 1], data[list[sum - 1]]);
return 0;
}