给定一个带整数键值的链表 L,你需要把其中绝对值重复的键值结点删掉。即对每个键值 K,只有第一个绝对值等于 K 的结点被保留。同时,所有被删除的结点须被保存在另一个链表上。例如给定 L 为 21→-15→-15→-7→15,你需要输出去重后的链表 21→-15→-7,还有被删除的链表 -15→15。
输入格式:
输出格式:
首先输出去重后的链表,然后输出被删除的链表。每个结点占一行,按输入的格式输出。
输入样例:
00100 5
99999 -7 87654
23854 -15 00000
87654 15 -1
00000 -15 99999
00100 21 23854输出样例:
00100 21 23854
23854 -15 99999
99999 -7 -1
00000 -15 87654
87654 15 -1
#include <stdio.h>
#include <math.h>
const int N=100010;
typedef struct List{
int address; //当前结点地址,输出被删除的链表时要用
int key; //键值
int next; //下一个结点的地址
}List;
int main()
{
int head,n;
scanf("%d %d",&head,&n);
List list[N]; //数组下标就是当前结点地址
int num[N],n_count=1; //键值绝对值,绝对值个数
List res[N];int r_count=0; //被删除的链表
for(int i=0;i<n;i++){ //获取链表
int dz,jz,xyg;
scanf("%d %d %d",&dz,&jz,&xyg);
list[dz].key=jz;
list[dz].next=xyg;
}
num[0]=abs(list[head].key); //绝对值数组初始化
int this=head; //当前结点的地址
int search; //被搜索结点的地址
while(list[this].next!=-1){
search=list[this].next;
for(int i=0;i<n_count;i++){
if(abs(list[search].key)==num[i]){ //需要删除
list[this].next=list[search].next; //更新当前结点的下一个结点地址
list[search].address=search; //记录被搜索的结点地址
list[search].next=-1;
if(r_count==0){
res[r_count++]=list[search]; //被搜索的结点被删除
}
else{
res[r_count-1].next=search;
res[r_count++]=list[search];
}
break;
}
else if(i==n_count-1){ //最后一次循环且不需要删除
num[n_count++]=abs(list[search].key); //增加新的绝对值
this=list[this].next; //被搜索的结点成为新的当前结点
break;
}
}
}
this=head;
while(list[this].next!=-1){ //输出去重后的链表
printf("%05d %d %05d\n",this,list[this].key,list[this].next);
this=list[this].next;
}
printf("%05d %d -1\n",this,list[this].key);
for(int i=0;i<r_count;i++){ //输出被删除链表
if(res[i].next!=-1)
printf("%05d %d %05d\n",res[i].address,res[i].key,res[i].next);
else
printf("%05d %d -1\n",res[i].address,res[i].key);
}
return 0;
}
注意事项:
输出的两个链表必须符合要求,从头到尾,除首尾结点外依次与前驱和后继连接。
最后两个测试点360+ms和350+ms,差点运行超时。
如有问题,欢迎提出。