两个有序链表序列的交集 (20 分)
已知两个非降序链表序列S1与S2,设计函数构造出S1与S2的交集新链表S3。
输入格式:
输入分两行,分别在每行给出由若干个正整数构成的非降序序列,用−1表示序列的结尾(−1不属于这个序列)。数字用空格间隔。
输出格式:
在一行中输出两个输入序列的交集序列,数字间用空格分开,结尾不能有多余空格;若新链表为空,输出NULL
。
输入样例:
1 2 5 -1
2 4 5 8 10 -1
输出样例:
2 5
/****************************************************************************************************/
这个题目一看就觉得 用数组一做就是啦,特别简单,但是用数组做了,把数组开的很大了,最后一个点就是过不了,就只能老老实实的用链表去做。
可是,为什么用数组就做不出来呢,那是因为你用一种情况没有考虑
例如
输入
1 2 2 2 2 2 -1
1 2 2 2 -1
输出
1 2 2 2
就是这种情况,题目中只说了“非降序 ”,那就可以是输出好几个相等的啊,所以,你可以用一个函数求出,a[i] b[i] 中小的哪一个,写个循环就OK了
当然,你还可以写个while()循环也是可以的
/*************************************************************************************/
方法一(不是链表)
#include<iostream>
using namespace std;
int a[10000005];
int b[10000005];
int min(int x,int y){
if(x<y)
return x;
else
return y;
}
int main(){
int x;
while(1){
cin>>x;
if(x==-1)
break;
else
a[x]++;
}
while(1){
cin>>x;
if(x==-1)
break;
else
b[x]++;
}
int temp=1;
for(int i=0;i<=10000005;i++){
if(a[i]>0&&b[i]>0){
for(int j=min(a[i],b[i]);j>0;j--){
if(temp==1)
cout<<i;
else
cout<<" "<<i;
temp++;
}
}
}
if(temp==1)
cout<<"NULL";
}
方法二(非链表,while())
#include<iostream>
using namespace std;
int a[1000005];
int b[1000005];
int main(){
int x;
while(1){
cin>>x;
if(x==-1)
break;
a[x]++;
}
while(1){
cin>>x;
if(x==-1)
break;
b[x]++;
}
int temp=1;
for(int i=0;i<=1000005;i++){
while(a[i]&&b[i]){
if(temp==1)
cout<<i;
else
cout<<" "<<i;
a[i]--;
b[i]--;
temp++;
}
}
if(temp==1)
cout<<"NULL";
}
方法三(链表)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct Node{
int Data;
struct Node* Next;
};//链表结构体
typedef struct Node* List;
List Creat(){
List head = (List)malloc(sizeof(struct Node));
List q;
head->Next = NULL;
q = head;//创建头结点的链表
int x;
while(~scanf("%d",&x)&&x!=-1){
List p = (List)malloc(sizeof(struct Node));
p->Data = x;
p->Next = NULL;//赋值操作
q->Next = p;//前一个的下一个为新创建的结点
q = p;//尾指针指向最后一个
}
return head;
} //求交集
List Merge(List a,List b){
a = a->Next;
b = b->Next;//分别指向第一个有效结点,跳过表头
List head = (List)malloc(sizeof(struct Node));
head->Next = NULL;
List q = head;
while(a&&b){
if(a==NULL||a->Data > b->Data){
b = b->Next;//如果a为空,或者a比b大,a不能移动了,b往后移找更大的
}
else if(b==NULL||b->Data > a->Data){
a = a->Next;//同理
}
else{//相同创建新的交集链表
List p = (List)malloc(sizeof(struct Node));
p->Data = b->Data;
p->Next = NULL;
q->Next = p;
q = p; //把相同的数据存在一个新链表中
a = a->Next;
b = b->Next;//同时移动到下一个
}
}
return head;
} //打印链表
void print(List L){
L= L->Next;
if(L==NULL){//为空输出NULL;
printf("NULL\n");
return;
}
int flag = 0;//控制输出的空格
while(L!=NULL){
if(!flag)
printf("%d",L->Data);
else
printf(" %d",L->Data);
flag = 1;
L = L->Next;
}
return;
}
int main(){
List a1 = Creat();
List a2 = Creat();
List temp = Merge(a1,a2);
print(temp);
return 0;
}