PTA---L2-002链表去重
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
PTA---L2-002链表去重
给定⼀个带整数键值的链表 L,你需要把其中绝对值重复的键值结点删掉。
即对每个键值 K,只有第⼀个绝对值等于 K 的结点被保留。
同时,所有被删除的结点须被保存在另⼀个链表上。
例如给定 L 为 21→-15→-15→-7→15,你需要输出去重后的链表 21→-15→-7,还有被删除的链表 -15→15。
输⼊格式:
输⼊在第⼀⾏给出 L 的第⼀个结点的地址和⼀个正整数 N(≤105,为结点总数)。
⼀个结点的地址是⾮负的 5 位整数,空地址 NULL ⽤ −1来表⽰。
随后 N ⾏,每⾏按以下格式描述⼀个结点:
地址键值下⼀个结点
其中地址是该结点的地址,键值是绝对值不超过104的整数,下⼀个结点是下个结点的地址。
输出格式:
⾸先输出去重后的链表,然后输出被删除的链表。
每个结点占⼀⾏,按输⼊的格式输出。
输⼊样例:
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<stdlib.h>
typedef struct{
int data;
int next;
}LQ[100005]; //把链表结点放⼊数组,利⽤数组的下标作为结点的地址
int flag[100005]; //由于题⽬是“去重”,所以,直接利⽤标签数组+下标来验证是否重复即可
int re[100005]; //这个数组放置的是去重完后的链表的结点的地址
int qu[100005]; //这个数组放置的是去重过程中,被去掉的结点的地址
int main(){
LQ LL;
int add,n;
scanf("%d %d",&add,&n);
int all = n;
int n1 = 0,n2 = 0;
while(n--){
int x,y,z;
scanf("%d %d %d",&x,&y,&z);
LL[x].data = y;
LL[x].next = z;
}
//读⼊完毕
//从链表的⾸地址add开始,往后遍历链表,直到链表的结束(add = -1),每次让add 等于所指向的结点指向的下⼀个结点位置【下标】
//通过判断标签数组中是否有该值,实现去重的功能
//对于没有重复值的结点,将其地址i 存⼊ re数组
//对于有重复值的结点,将其地址i 存⼊qu数组
for(int i = add;i != -1;i = LL[i].next){
int m = abs(LL[i].data);
if(flag[m] == 0){
flag[m] = 1;
re[n1++] = i; //注意这⾥内部是 n1++
}else{
qu[n2++] = i;
}
}
//打印去除结点的链表 --- re 数组
for(int i = 0; i < n1;i++){
if(i == n1 -1 )
printf("%05d %d -1\n",re[i],LL[re[i]].data);
else
printf("%05d %d %05d\n",re[i],LL[re[i]].data,re[i+1]);
}
//可以看出来,re[n1++] ,qu[n2++] 的⽬的就是利⽤⼀个存放地址的数组的向后遍历实现链表结点间地址的“连续” //(通过 re[i+1] 访问下⼀个结点的地址)
//同时,re,qu ⾥⾯存储了相应结点的地址,可以通过结构体数组LL快速访问该结点的值
//打印被去掉的结点构成的链表 --- qu 数组
for(int i = 0; i < n2;i++){
if(i == n2 -1 )
printf("%05d %d -1\n",qu[i],LL[qu[i]].data);
else
printf("%05d %d %05d\n",qu[i],LL[qu[i]].data,qu[i+1]);
}
return0;
}。