L2-002. 链表去重
给定一个带整数键值的单链表L,本题要求你编写程序,删除那些键值的绝对值有重复的结点。即对任意键值K,只有键值或其绝对值等于K的第一个结点可以被保留。同时,所有被删除的结点必须被保存在另外一个链表中。例如:另L为21→-15→-15→-7→15,则你必须输出去重后的链表21→-15→-7、以及被删除的链表-15→15。【删除后的节点全部接到一个新的链表里】
输入格式:
输入第一行包含链表第一个结点的地址、以及结点个数N(<= 105 的正整数)【数据范围不大,可以考虑用结构体数组存贮整体信息】。结点地址是一个非负的5位整数,NULL指针用-1表示。
随后N行,每行按下列格式给出一个结点的信息:
Address Key Next
其中Address是结点的地址,Key是绝对值不超过104的整数,Next是下一个结点的地址。
输出格式:
首先输出去重后的链表,然后输出被删除结点组成的链表。每个结点占一行,按输入的格式输出。
输入样例:00100 5 99999 -7 87654 23854 -15 00000 87654 15 -1 00000 -15 99999 00100 21 23854
【输出时,要求分成两部分进行处理!每个地址要求占到5位,但是-1需要特殊考虑!】
AC题解:
还是用数组模拟的链表哦!
befadd是“before-address”的简写,表示第一个链表的当前需要插入的节点的上个节点!
befadd2是“before-address2”的简写,表示第二个链表表示废弃链表的当前需要插入的节点的上个节点!
注意每次都要及时封住链表的尾部!
#include<iostream> #include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> #include<queue> #include<set> #include<string> #include<map> #define maxn 400000 #define inf 0x3f3f3f3f using namespace std; #define N 100008 struct node{ int key,next; }a[N]; int beg1,beg2;//两个链表的开头 bool vis[N]; int main(){ int n; while(scanf("%d%d",&beg1,&n)!=EOF){ int add,key,next; for(int i=0;i<n;i++){ scanf("%d%d%d",&add,&key,&next); a[add].key=key,a[add].next=next; } memset(vis,false,sizeof(vis)); int u=beg1; beg2=-1; int bef1add=-1; int befadd; while(u!=-1){ if(vis[abs(a[u].key)]==true){//加入废弃的链接节点里 int u2=a[u].next; if(beg2==-1){ beg2=u; befadd=u; a[u].next=-1; }else{ a[befadd].next=u; a[u].next=-1; befadd=u; } u=u2; } else{//非废弃的链表 if(bef1add!=-1){ a[bef1add].next=u; bef1add=-1; } vis[abs(a[u].key)]=true; int u2=a[u].next; if(vis[abs(a[u2].key)]==true){ a[u].next=-1; bef1add=u; } u=u2; } } //输出 cout<<endl; while(beg1!=-1){ if(a[beg1].next==-1) printf("%05d %d %d ",beg1,a[beg1].key,-1); else printf("%05d %d %05d ",beg1,a[beg1].key,a[beg1].next); beg1=a[beg1].next; } while(beg2!=-1){ if(a[beg2].next==-1) printf("%05d %d %d ",beg2,a[beg2].key,-1); else printf("%05d %d %05d ",beg2,a[beg2].key,a[beg2].next); beg2=a[beg2].next; } } return 0; }