1. 程式人生 > >PTA 兩個有序連結串列序列的交集 (很簡單 不是用連結串列做的)

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;
}