链表去重
附连接:L2-002 链表去重 (25 分)
给定一个带整数键值的链表 L,你需要把其中绝对值重复的键值结点删掉。即对每个键值 K,只有第一个绝对值等于 K 的结点被保留。同时,所有被删除的结点须被保存在另一个链表上。例如给定 L 为 21→-15→-15→-7→15,你需要输出去重后的链表 21→-15→-7,还有被删除的链表 -15→15
今天做题又遇到了…第三次了,做了好久,还是错的,学习了一下,记录记录。刚刚写的时候len1,len2没给初始值,又卡了半天…
思路简单,1.用数组存储元素, 2.使用数组存储地址,两个数组存储两类地址->未重复的,重复的,并用两个变量记录两个数组的长度。3.最后输出即可
代码如下:
#include<math.h>
#include<stdio.h>
struct node
{
int key,next;
}a[100010];//存放链表,值和下一个的地址
int start,n;
int firarray[100010],secarray[100010];///两个数组,分别用来存放不重复的结点的首地址,重复淘汰结点的首地址
int repeat[1000010];
int main()
{
scanf("%d%d",&start,&n);
for(int i=0;i<n;i++)
{
int q,w,e;
scanf("%d%d%d",&q,&w,&e);
a[q].key=w;
a[q].next=e;
}
int len1,len2;//记录两个数组的长度
len1=len2=0;
for(int i=start;i>-1;i=a[i].next)
{
int key=fabs(a[i].key);
if(repeat[key]==0)///判断这个数出现过没有,没出现过将这个数标记为1,并将地址加入firarray数组中
{
repeat[key]=1;
firarray[len1++]=i;
}
else///出现过就将当前位置的地址加入secarray中
{
secarray[len2++]=i;
}
}
for(int i=0;i<len1;i++)///输出,当到最后一个位置时输出-1
{
printf("%05d %d ",firarray[i],a[firarray[i]].key);
if(i==len1-1)
printf("-1\n");
else
printf("%05d\n",firarray[i+1]);
}
for(int i=0;i<len2;i++)
{
printf("%05d %d ",secarray[i],a[secarray[i]].key);
if(i==len2-1)
printf("-1\n");
else
printf("%05d\n",secarray[i+1]);
}
return 0;
}
结果: