1025 反转链表(25 分)
给定一个常数 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
(25 分)
给定一个常数 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
#include
#include
#include
#include
#include
using namespace std;
struct link{
string address;
int data;
string next;
};
int main()
{
//fstream fin("D://summer//PAT//1025//input.txt", ios::in);
//fstream fout("D://summer//PAT//1025//output.txt", ios::out);
string begin;//开始地址
string next;
int n, k;//结点总个数正整数 N 、以及正整数 K 个节点反转
link temp;
vector l;//单链表
cin >> begin >> n >> k;
for (int i = 0; i < n; i++)
{
cin >> temp.address >> temp.data >> temp.next;//从文件中读取单链表
l.push_back(temp);
}
next = begin;
vector x;
while (next != "-1")
{
for (int i = 0; i < l.size(); i++) //顺序后的链表
{
if (l[i].address == begin)
{
x.push_back(l[i]);
begin = l[i].next;
next = l[i].next;
}
}
}
//反转
//reverse(x.begin(), x.begin() + k);
for (int i = 0; (i+1) * k <= x.size(); i++)
{
reverse(x.begin() + i*k, x.begin() + (i + 1)*k);
}
for (int i = 0; i < x.size(); i++)
{
cout << x[i].address << " " << x[i].data << " " << x[i].next << endl;
}
system("pause");
return 0;
}
填坑:
1、输出的节点 next要改
2、输出的最后一个节点的next为-1,注意是字符串!
#include
#include
#include
#include
#include
using namespace std;
struct link{
string address;
int data;
string next;
};
int main()
{
//fstream fin("D://summer//PAT//1025//input.txt", ios::in);
//fstream fout("D://summer//PAT//1025//output.txt", ios::out);
string begin;//开始地址
string next;
int n, k;//结点总个数正整数 N 、以及正整数 K 个节点反转
link temp;
vector l;//单链表
cin >> begin >> n >> k;
for (int i = 0; i < n; i++)
{
cin >> temp.address >> temp.data >> temp.next;//从文件中读取单链表
l.push_back(temp);
}
next = begin;
vector x;
while (next != "-1")
{
for (int i = 0; i < l.size(); i++) //顺序后的链表
{
if (l[i].address == begin)
{
x.push_back(l[i]);
begin = l[i].next;
next = l[i].next;
break;
}
}
}
//反转
//reverse(x.begin(), x.begin() + k);
for (int i = 0; (i+1) * k <= x.size(); i++)
{
reverse(x.begin() + i*k, x.begin() + (i + 1)*k);
}
//改next
for (int i = 0; i < x.size() - 1; i++)
{
x[i].next = x[i + 1].address;
}
x[x.size() - 1].next = "-1";//
//输出
for (int i = 0; i < x.size(); i++)
{
cout << x[i].address << " " << x[i].data << " " << x[i].next << endl;
}
system("pause");
return 0;
}
改为int 和 scanf还是运行超时……不过耗时短了
#include
#include
#include
#include
#include
using namespace std;
struct link{
int address;
int data;
int next;
};
int main()
{
//fstream fin("D://summer//PAT//1025//input.txt", ios::in);
//fstream fout("D://summer//PAT//1025//output.txt", ios::out);
int begin;//开始地址
int next;
int n, k;//结点总个数正整数 N 、以及正整数 K 个节点反转
link temp;
vector l;//单链表
scanf("%d%d%d", &begin, &n, &k);
//fin >> begin >> n >> k;
for (int i = 0; i < n; i++)
{
scanf("%d%d%d", &temp.address, &temp.data, &temp.next);
//fin >> temp.address >> temp.data >> temp.next;//从文件中读取单链表
l.push_back(temp);
}
next = begin;
vector x;
while (next != -1)
{
for (int i = 0; i < l.size(); i++) //顺序后的链表
{
if (l[i].address == begin)
{
x.push_back(l[i]);
begin = l[i].next;
next = l[i].next;
break;
}
}
}
//反转
//reverse(x.begin(), x.begin() + k);
for (int i = 0; (i+1) * k <= x.size(); i++)
{
if ((i + 1)*k <= x.size())
reverse(x.begin() + i*k, x.begin() + (i + 1)*k);
}
//改next
for (int i = 0; i < x.size() - 1; i++)
{
x[i].next = x[i + 1].address;
}
x[x.size() - 1].next = -1;//
for (int i = 0; i < x.size() - 1; i++)
{
printf("%05d %d %05d\n", x[i].address, x[i].data, x[i].next);
//fout << x[i].address << " " << x[i].data << " " << x[i].next << endl;
}
printf("%05d %d -1", x[x.size()-1].address, x[x.size()-1].data);
system("pause");
return 0;
}
用了l.erase(l.begin() + i); 测试点1和6反而时间更长
思路:
定义一个结构体数组来储存一开始的链表
数组下标对应链表的地址,这样就不用一直循环来找地址了
(注意数组下标100000,next的寻址不能在begin之后 或者 不能=a[begin].next)
#include
#include
#include
#include
#include
using namespace std;
struct link{
int address;
int data;
int next;
};
int main()
{
//fstream fin("D://summer//PAT//1025//input.txt", ios::in);
//fstream fout("D://summer//PAT//1025//output.txt", ios::out);
int begin;//开始地址
int next;
int n, k;//结点总个数正整数 N 、以及正整数 K 个节点反转
link temp;
link a[100000];//根据数组下标存链表数据、不能少个0
int index;
vector l;//单链表
scanf("%d%d%d", &begin, &n, &k);
//fin >> begin >> n >> k;
for (int i = 0; i < n; i++)
{
scanf("%d%d%d", &temp.address, &temp.data, &temp.next);
//fin >> temp.address >> temp.data >> temp.next;//从文件中读取单链表
//l.push_back(temp);
a[temp.address] = temp;
}
next = begin;
vector x;
while (next != -1)
{
x.push_back(a[begin]);
begin = a[begin].next;
next = begin;//这里要注意
}
//反转
//reverse(x.begin(), x.begin() + k);
for (int i = 0; (i + 1) * k <= x.size(); i++)
{
if ((i + 1)*k <= x.size())
reverse(x.begin() + i*k, x.begin() + (i + 1)*k);
}
//改next
for (int i = 0; i < x.size() - 1; i++)
{
x[i].next = x[i + 1].address;
}
x[x.size() - 1].next = -1;//
for (int i = 0; i < x.size() - 1; i++)
{
printf("%05d %d %05d\n", x[i].address, x[i].data, x[i].next);
//fout << x[i].address << " " << x[i].data << " " << x[i].next << endl;
}
printf("%05d %d -1", x[x.size() - 1].address, x[x.size() - 1].data);
system("pause");
return 0;
}