PTA 两个有序链表序列的交集 (很简单 不是用链表做的)

 两个有序链表序列的交集 (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;
}

猜你喜欢

转载自blog.csdn.net/red_red_red/article/details/84398050