题目大意:
给定N个结点起始地址为$begin$_$address$的单链表,要求根据data进行排序,然后输出链表
算法思路:
我们首先用$node$数组存储所有输入的结点,在输入的时候使用$dataToAddress$记录数据到地址的映射(数据和地址是绑定的,无论怎么样都不会变化),由于对于输入可能会有不在链表上的结点,所以使用$isExist$记录所有输入的节点,这样就可以判断起始节点是否存在输入节点中,目的是为了解决链表为空的情况。对于只有部分有效节点的情况,我们需要遍历$node$数组,并使用$data$数组保存所有在链表中的节点的数据,$count$记录有效节点的个数,这里排序采用的是索引排序的技巧,直接对$data$数组排序,那么再利用$dataToAddress$就可以方便的知道对应节点的地址,并且$next$就是下一个节点的$address$,不过得注意,最后一个节点的$next$为-1,需要手动赋值,同时需要记录新的起始地址为$data$数组中第一个节点的地址。最后按照要求进行输出即可
注意点:
1、输入节点会出现无效的情况,所以得遍历输入节点,保存有效节点的信息,测试点1和4考察。
2、测试点4考察所有节点都是无效的情况,这个时候得输出"0 -1"
3、地址保留5位有效数字,-1得特判。
提交结果:
AC代码:
#include <cstdio>
#include <unordered_map>
#include <algorithm>
using namespace std;
struct Node{
int address;
int data;
int next;
}node[100005];
unordered_map<int,int> dataToAddress;
unordered_map<int,bool > isExist;
int main(){
int N,begin_address;
scanf("%d %d",&N,&begin_address);
Node p{};
for (int i = 0; i < N; ++i) {
scanf("%d %d %d",&p.address,&p.data,&p.next);
node[p.address] = p;
dataToAddress[p.data] = p.address;
isExist[p.address] = true;
}
if(!isExist[begin_address]){
printf("0 -1\n");
return 0;
}
int data[N];// 保存所有的数据
int count = 0;//链表上的节点个数
for (int address = begin_address; address !=-1 ; address=node[address].next) {
data[count++] = node[address].data;
}
sort(data,data+count);
for (int i = 0; i < count-1; ++i) {
int address = dataToAddress[data[i]];
int nextAddress = dataToAddress[data[i+1]];
node[address].next = nextAddress;
if(i==0){
// 记录新的起始地址
begin_address = address;
}
}
// 最后一个节点的下一个节点地址为-1
node[dataToAddress[data[count-1]]].next = -1;
printf("%d %05d\n",count,begin_address);
while (begin_address!=-1){
if(node[begin_address].next!=-1){
printf("%05d %d %05d\n",node[begin_address].address,node[begin_address].data,node[begin_address].next);
} else {
printf("%05d %d -1\n",node[begin_address].address,node[begin_address].data);
}
begin_address = node[begin_address].next;
}
return 0;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。