1025 反转链表 (25)(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(<= 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
数据结构:
本题思路将所有的节点,按节点间的次序关系排放,再将节点进行逆转,最后输出
难点有二
1、将输入次序混乱的节点整理次序
2、节点的逆转使用reverse()函数
由于时间上容易超时,将空间来换取时间,设立三个数组data[100000]、next[100000]、list[100000]
此处我们将地址转换为数组下标,可在查找方面省时许多,将排好序的节点地址存储在list[]数组中,方便之后逆转
此处还有健硕性的考量,输入的所有节点并不一定都可以串成链表
本代码和思想参考了https://www.liuchuo.net/archives/463
#include<iostream> #include<stdlib.h> #include<algorithm> using namespace std; int main() { int start, N, K;//起始节点地址,总结点个数,反转的节点个数 cin >> start >> N >> K; /*初始化数据*/ int data[100000];//记录对应地址的数据 int next[100000];//存储下一节点的地址 int list[100000];//表现节点间的先后次序 for (int i = 0; i < N; i++) { int address; cin >> address; cin >> data[address] >> next[address]; } /*将节点按照先后顺序排列*/ int sum = 0;// for (int i = 0; start != -1; i++) { list[i] = start; start = next[start]; sum++; } /*反转*/ for (int i = 0; i < sum / K; i++) { reverse(list + i * K, list + (i + 1) * K); } /*输出*/ for (int i = 0; i < sum; i++) { if (i == sum - 1) printf("%05d %d -1 ", list[i], data[list[i]]); else printf("%05d %d %05d ", list[i], data[list[i]], list[i + 1]); } system("pause"); return 0; }