难顶,最开始想用链表的,后来操作太麻烦,就使用了数组实现。思路如下:
- 输入格式
Address Data Next
00100 6 4
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218
- 思路
一行表示一个元素,其中第一列表示该元素的地址,第二列表示该地址内存放的元素的值,第三列表示该元素下一个元素的地址。
在本题中,仅要求对序列顺序进行改变,而没有要求改变值。所以每个地址所对应的值是不变的,即第一列和第二列是保持同步的。仅有第三列改变。
-
步骤
- 存储:构建数组分别存储Data和Next,并使用数组下标作为Address。同时,为方便逆序,使用list数组按顺序保存首地址。
- 排序:注意输入的num不一定就是所以要操作的元素数,因为还有游离于链表之外的元素不参与逆序。
- 逆序:每k个进行一次逆序,逆序操作主要是修改next以达到逆序的目的。直接交换很麻烦,这时候就要用到辅助list数组了。先将辅助数组list每k个交换过来(很简单,不赘述了),然后根据list的次序逐个修改即可。
- 输出:到-1即可。
-
代码
#include<iostream>
using namespace std;
#define MaxSize 100005
//选择合适的存储方式
int main() {
//定义
int data[MaxSize], next[MaxSize], list[MaxSize];
int num, k;
int start, pos;
int i, j, temp;
//输入
cin >> start >> num >> k;
for (i = 0; i < num; i++) {
cin >> pos; cin >> data[pos]; cin >> next[pos];
}
//排序并构建list
pos = start;
int sum = 0;
while(pos != -1) { //不能用num,因为可能多余结点
list[sum++] = pos;
pos = next[pos];
}
//对list进行每k个逆序操作
for (i = 0; i < sum / k; i++) {
for (j = 0; j < k / 2; j++) {
temp = list[j + i * k];
list[j + i * k] = list[(i + 1) * k - (j) - 1];
list[(i + 1) * k - (j) - 1] = temp;
}
}
//根据逆序过后的list修改next
pos = start = list[0];
for (i = 0; i < sum - 1; i++) {
pos = next[pos] = list[i + 1];
}
next[list[sum - 1]] = -1;
//输出
pos = start;
for (i = 0; i<sum-1; i++){
printf("%05d %d %05d\n", list[i], data[list[i]], next[list[i]]);
}
printf("%05d %d %d\n", list[i], data[list[i]], next[list[i]]);
return 0;
}