[TOC]
7-1 两个有序链表序列的交集
已知两个非降序链表序列S1与S2,设计函数构造出S1与S2的交集新链表S3。
输入格式:
输入分两行,分别在每行给出由若干个正整数构成的非降序序列,用−1表示序列的结尾(−1不属于这个序列)。数字用空格间隔。
输出格式:
在一行中输出两个输入序列的交集序列,数字间用空格分开,结尾不能有多余空格;若新链表为空,输出NULL
。
输入样例:
输出样例:
代码实现:
这段程序的通过难点主要在于关心交集为空的情况,分为两种:
①集合1和集合2之间最少有一个为空
②集合1和集合2不是空集,但是相同元素的个数为0
针对第二种情况,只需要设置一个计数器i=0,当集合1的元素==集合2的元素时,i++,若运行到循环结束,i仍然为0,说明得到的交集为空
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
| #include<iostream> using namespace std; typedef struct LNode{ int data; struct LNode *next; }LNode,*LinkList;
int creatlist(LinkList &S1,LinkList &S2){ LNode *p1,*p2,*r; p1=S1,p2=S2; r=S1; while(1){ p1=new LNode; cin>>p1->data; if(p1->data==-1) break;//在链表录入-1前结束循环 p1->next=NULL; r->next=p1; r=p1; }//尾插法 r=S2;//循环利用变量r while(1){ p2=new LNode; cin>>p2->data; if(p2->data==-1) break; p2->next=NULL; r->next=p2; r=p2; }//尾插法 return 1; }
int jiaoji(LinkList &S1,LinkList &S2){ LNode *S3,*p3,*r; LNode *p1,*p2; p1=S1->next,p2=S2->next; S3=new LNode; S3->next=NULL; r=S3; int i=0;//统计S3的长度 if(S1==NULL || S2==NULL){ cout<<"NULL"; return 0; } while(p1&&p2){ if(p1->data==p2->data){ i++; p3=new LNode; p3->data=p1->data; p3->next=NULL; r->next=p3; r=p3; p1=p1->next; p2=p2->next; }else if(p1->data>p2->data) p2=p2->next; else if(p1->data<p2->data) p1=p1->next; } if(i==0) { cout<<"NULL"; return 0; } p3=S3->next;//p3重新退回头结点指向的位置 while(p3->next){ cout<<p3->data<<" "; p3=p3->next; }cout<<p3->data; return 1; }
int main(){ LNode *S1,*S2; S1=new LNode; S1->next=NULL; S2=new LNode; S2->next=NULL; creatlist(S1,S2); jiaoji(S1,S2); return 0; }
|
|
|
|
|
|
|
|
测试点 |
提示 |
内存(KB) |
用时(ms) |
结果 |
得分 |
|
0 |
样例等价 |
300 |
2 |
答案正确 |
2 / 2 |
|
1 |
交集为空 |
488 |
3 |
答案正确 |
2 / 2 |
|
2 |
完全相交 |
276 |
3 |
答案正确 |
2 / 2 |
|
3 |
其中一个序列完全属于交集 |
492 |
2 |
答案正确 |
2 / 2 |
|
4 |
其中一个序列为空 |
492 |
3 |
答案正确 |
2 / 2 |
|
5 |
大规模数据 |
31864 |
291 |
答案正确 |
2 / 2 |
|
7-2 两个有序链表序列的合并
已知两个非降序链表序列S1与S2,设计函数构造出S1与S2合并后的新的非降序链表S3。
输入格式:
输入分两行,分别在每行给出由若干个正整数构成的非降序序列,用−1表示序列的结尾(−1不属于这个序列)。数字用空格间隔。
输出格式:
在一行中输出合并后新的非降序链表,数字间用空格分开,结尾不能有多余空格;若新链表为空,输出NULL
。
输入样例:
输出样例:
代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| #include<iostream> using namespace std; typedef struct LNode{ int data; struct LNode *next; }LNode,*LinkList;
int creatlist(LinkList &S1,LinkList &S2){ LNode *p1,*p2,*r; r=S1; while(1){ p1=new LNode; cin>>p1->data; if(p1->data==-1) break; p1->next=NULL; r->next=p1; r=p1; } r=S2; while(1){ p2=new LNode; cin>>p2->data; if(p2->data==-1) break; p2->next=NULL; r->next=p2; r=p2; } return 1; } int bingji(LinkList &S1,LinkList &S2){ LNode *p1,*p2; p1=S1->next,p2=S2->next; LNode *S3,*p3; S3=S1; p3=S3; while(p1&&p2){ if(p1->data<=p2->data){ p3->next=p1; p3=p1; p1=p1->next; }else{ p3->next=p2; p3=p2; p2=p2->next; } } p3->next=p1?p1:p2; //三目运算符,等价于 //if(p1)p3->next=p1; //else if(p2)p3-a.next=p2; free(S2);//释放头结点 p3=S3->next; if(p3==NULL){ cout<<"NULL"; return 0; } while(p3->next){ cout<<p3->data<<" "; p3=p3->next; }cout<<p3->data;
return 1;
} int main(){ LNode *S1,*S2; S1=new LNode,S2=new LNode; S1->next=NULL,S2->next=NULL; creatlist(S1,S2); bingji(S1,S2); return 0; }
|
测试点 |
提示 |
内存(KB) |
用时(ms) |
结果 |
得分 |
|
0 |
样例等价 |
400 |
2 |
答案正确 |
5 / 5 |
|
1 |
有并列 |
288 |
2 |
答案正确 |
5 / 5 |
|
2 |
链表为空 |
400 |
2 |
答案正确 |
5 / 5 |
|
3 |
大规模输入 |
46228 |
370 |
答案正确 |
5 / 5 |
|
7-3 两个有序链表合并(新表不含重复元素)
已知两个非降序链表序列S1与S2,设计函数构造出S1与S2合并后的新的非降序链表S3。
要求S3中没有重复元素。
输入格式:
输入分两行,分别在每行给出由若干个正整数构成的非降序序列,用−1表示序列的结尾(−1不属于这个序列)。数字用空格间隔。
输出格式:
在一行中输出合并后新的非降序链表,要求链表中没有重复元素。数字间用空格分开,结尾不能有多余空格;若新链表为空,输出NULL。
输入样例:
在这里给出一组输入。例如:
1 2
| 1 3 3 5 8 -1 2 3 4 6 8 10 -1
|
输出样例:
在这里给出相应的输出。例如:
代码实现:
这一段程序相对于上一题的难点在于:
①要求并集中的元素不可重复,因此必须细致的分类讨论集合1大于、小于或等于集合2,以及集合1和集合2的值分别等不等于并集已存在的值
②设置了测试点:一个是空表,一个只有两个相同的元素。如果不加上p3->next=NULL,程序会报错
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
| #include<iostream> using namespace std; typedef struct LNode{ int data; struct LNode *next; }LNode,*LinkList;
int creatlist(LinkList &S1,LinkList &S2){ LNode *p1,*p2,*r; r=S1; while(1){ p1=new LNode; cin>>p1->data; if(p1->data==-1) break; p1->next=NULL; r->next=p1; r=p1; } r=S2; while(1){ p2=new LNode; cin>>p2->data; if(p2->data==-1) break; p2->next=NULL; r->next=p2; r=p2; } return 1; } int bingji(LinkList &S1,LinkList &S2){ LNode *p1,*p2; p1=S1->next,p2=S2->next; LNode *S3,*p3; S3=S1; p3=S3; while(p1&&p2){ if(p1->data<p2->data &&p1->data!=p3->data){ p3->next=p1; p3=p1; p1=p1->next; }else if(p1->data>p2->data&&p2->data!=p3->data){ p3->next=p2; p3=p2; p2=p2->next; }else if(p1->data==p2->data&&p1->data!=p3->data){ p3->next=p1; p3=p1; p1=p1->next; p2=p2->next; }else if(p1->data==p3->data) p1=p1->next; else if(p2->data==p3->data) p2=p2->next; } while(p1){ if(p3->data!=p1->data){ p3->next=p1; p3=p1; } p1=p1->next; } while(p2){ if(p3->data!=p2->data){ p3->next=p2; p3=p2; } p2=p2->next; }//不能简单地使用三目运算符,因为必须考虑值相等的情况 p3->next=NULL;//如果没有这一条,会报错一个测试点 free(S2);//释放头结点 p3=S3->next; if(p3==NULL){ cout<<"NULL"; return 0; } while(p3->next){ cout<<p3->data<<" "; p3=p3->next; }cout<<p3->data;
return 1;
} int main(){ LNode *S1,*S2; S1=new LNode,S2=new LNode; S1->next=NULL,S2->next=NULL; creatlist(S1,S2); bingji(S1,S2); return 0; }
|
|
|
|
|
|
|
|
测试点 |
提示 |
内存(KB) |
用时(ms) |
结果 |
得分 |
|
0 |
样例 |
316 |
2 |
答案正确 |
5 / 5 |
|
1 |
一个是空表,另一个只有两个相同元素 |
316 |
2 |
答案正确 |
5 / 5 |
|
2 |
两个表都只有一个元素且相同 |
316 |
2 |
答案正确 |
5 / 5 |
|
3 |
两个表有很多相同元素 |
452 |
2 |
答案正确 |
5 / 5 |
|