给定一个带整数键值的链表 L,你须要把其中绝对值重复的键值结点删掉。即对每一个键值 K,只有第一个绝对值等于 K 的结点被保留。同时,全部被删除的结点须被保存在另外一个链表上。例如给定 L 为 21→-15→-15→-7→15,你须要输出去重后的链表 21→-15→-7,还有被删除的链表 -15→15。node
输入格式:数组
输入在第一行给出 L 的第一个结点的地址和一个正整数 N(≤105,为结点总数)。一个结点的地址是非负的 5 位整数,空地址 NULL 用 -1 来表示。spa
随后 N 行,每行按如下格式描述一个结点:code
地址 键值 下一个结点
其中地址
是该结点的地址,键值
是绝对值不超过104的整数,下一个结点
是下个结点的地址。string
输出格式:it
首先输出去重后的链表,而后输出被删除的链表。每一个结点占一行,按输入的格式输出。io
输入样例:class
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<math.h> #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int N=1e5+10;//数据范围; int s,n,k=0,m=0; int book[N];//记录这个键值是否存在过; int b[N],c[N];//存储两个链表; struct node { int num;//键值; int end;//下一个节点的编号; } a[N]; void solve() { int x=s; while(x!=-1)//链表终止; { int kk=fabs(a[x].num);//绝对值; if(book[kk]==0)//键值不存在,即第一次出现; { b[k++]=x;//存储下来; book[kk]=1;//改变,即该键值已经出现过; } else { c[m++]=x;//存储; } x=a[x].end;//下一个的编号; } return ; } void prin()//输出,注意格式便可; { printf("%05d",s); for(int i=1; i<k; i++) printf(" %d %05d\n%05d",a[b[i-1]].num,b[i],b[i]); printf(" %d -1\n",a[b[k-1]].num); if(m>0)//注意细节; { printf("%05d",c[0]); for(int i=1; i<m; i++) printf(" %d %05d\n%05d",a[c[i-1]].num,c[i],c[i]); printf(" %d -1\n",a[c[m-1]].num); } } int main() { while(~scanf("%d%d",&s,&n)) { int ww; for(int i=0; i<n; i++) { scanf("%d",&ww); scanf("%d%d",&a[ww].num,&a[ww].end);//注意存储方法; }//这样的存储在查询时不用搜索了,不然会超时; memset(book,0,sizeof book);//标记数组初始化; solve();//解决; prin();//输出; } return 0; }