前面是算法笔记的代码,比较繁琐,后两种是网上找的,放在这里日后对比学习一下。
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 100010;
struct Node { //定义静态链表
int address;
int data;
int next;
int order;
}node[maxn];
bool cmp(Node a, Node b) {
return a.order < b.order;
}
int main() {
for (int i = 0; i < maxn; ++i) {
node[i].order = maxn; //初始化链表结点为无效结点
}
int begin, num, K, address;
scanf("%d%d%d", &begin, &num, &K); //起始地址,结点总数,步长
for (int i = 0; i < num; ++i) {
scanf("%d", &address);
scanf("%d%d", &node[address].data, &node[address].next);
node[address].address = address;
}
int p = begin, count = 0;
while (p != -1) { //遍历找出所有有效结点
node[p].order = count++; //结点在单链表中的序号
p = node[p].next; //下一个结点地址
}
sort(node, node + maxn, cmp); //将单链表按照order进行排序
//有效链表结点为前count个结点,为了书写方便,将其赋值给n
int n = count;
for (int i = 0; i < n / K; ++i) { //枚举完整的n / K 块
for (int j = (i + 1) * K - 1; j > i * K; --j) { //第i个块倒着输出
printf("%05d %d %05d\n", node[j].address, node[j].data, node[j - 1].address);
}
//下面是每一块最后一个结点的next地址的处理
printf("%05d %d ", node[i * K].address, node[i * K].data);
if (i < n / K - 1) {
//如果不是最后一块,那么指向下一块最后一个结点的地址
printf("%05d\n", node[(i + 2) * K - 1].address);
}
else {
if (n % K == 0) {
//是最后一块,且后面没有不完整的块,则其实最后一个结点
printf("-1\n");
}
else {
printf("%05d\n", node[(i + 1) * K].address);
for (int i = n / K * K; i < n; ++i) {
printf("%05d %d ", node[i].address, node[i].data);
if (i < n - 1) {
printf("%05d\n", node[i].next);
}
else {
printf("-1\n");
}
}
}
}
}
system("pause");
return 0;
}
别人的代码
//#include<iostream>
//#include<algorithm>
//#include<vector>
//using namespace std;
//const int maxn = 1e5 + 10;
//struct Node
//{
// int add, data, next;
//}node[maxn];
//void init()
//{
// for (int i = 0; i < maxn; i++)node[i].add = i;
//}
//int head, n, k;
//vector<Node>list;
//int main()
//{
// scanf("%d%d%d", &head, &n, &k);
// init();
// for (int i = 0; i < n; i++)
// {
// int address;
// scanf("%d", &address);
// scanf("%d%d", &node[address].data, &node[address].next);
// }
// int p = head;
// while (p != -1)
// {
// list.push_back(node[p]);
// p = node[p].next;
// }
// int group = list.size() / k;
// for (int i = 0; i < group; i++)
// {
// reverse(list.begin() + i * k, list.begin() + i * k + k);
// }
// for (int i = 0; i < list.size(); i++)
// {
// printf("%05d %d ", list[i].add, list[i].data);
// if (i != list.size() - 1)printf("%05d", list[i + 1].add);
// else printf("-1");
// printf("\n");
// }
// return 0;
//}
//
//
//
///别人的代码
//#include<iostream>
//#include<algorithm>
//using namespace std;
//const int maxn = 1e5 + 10;
//int w[maxn], nt[maxn], f[maxn];
//int s, n, k, x, cnt;
//int main()
//{
// scanf("%d%d%d", &s, &n, &k);
// for (int i = 0; i < n; i++) { scanf("%d", &x); scanf("%d%d", &w[x], &nt[x]); }//地址的值读入w[x]中,下一个地址读入nt[x]
// for (int i = s; i != -1; i = nt[i])f[cnt++] = i;//这个很常用,在地址这边(儿子的儿子的儿子)
// for (int i = 0; i + k <= cnt; i += k) //每k个里面
// for (int j = 0; j < k; j++)//这个画一下就知道了,头一个和最后一个交换
// {
// if (i + j > i + k - j - 1)break;
// else swap(f[i + j], f[i + k - j - 1]);
// }
// for (int i = 0; i < cnt; i++)
// {
// if (i < cnt - 1)printf("%05d %d %05d\n", f[i], w[f[i]], f[i + 1]);
// else printf("%05d %d -1\n", f[i], w[f[i]]);
// }
// return 0;
//}