题目描述:
已知两个非降序链表序列S1与S2,设计函数构造出S1与S2的交集新链表S3。
输入格式:
输入分两行,分别在每行给出由若干个正整数构成的非降序序列,用−1表示序列的结尾(−1不属于这个序列)。数字用空格间隔。
输出格式:
在一行中输出两个输入序列的交集序列,数字间用空格分开,结尾不能有多余空格;若新链表为空,输出NULL
。
输入样例:
1 2 5 -1
2 4 5 8 10 -1
结尾无空行
输出样例:
2 5
题目分析:
链表的创建是基本知识,这里不再赘述。本题在创建了两个链表之后,利用FindIntersection()函数求交集。函数体里创建了一个新链表L3用来当做结果链表。只要L1,L2链表非空,那么每次都取p1,p2(分别指向L1,L2)两个指针指向的链表的相应位置,取其data进行比较,如果相等,则插入到L3中,否则小的链表指针后移,直到有一链表为空退出。
代码实现:
#include<stdio.h>
#include<stdlib.h>
typedef int ElementType;
typedef struct LNode{
ElementType Data;
struct LNode *Next;
}LNode,*LinkList;
LNode *Init_List(){ //创建带头指针的空链表,返回其头指针
LNode *Head;
Head=(LNode *)malloc(sizeof(LNode));
Head->Next=NULL;
return Head;
}
LinkList CreateList(){ //链表根据输入进行创建,到-1结束。
int n;
LinkList L=Init_List();
LNode *node=L;
while(scanf("%d",&n)!=EOF){
if(n==-1) break;
LNode *p=(LNode *)malloc(sizeof(LNode));
p->Data=n;
node->Next=p;
node=node->Next;
}
node->Next=NULL;
return L;
}
LinkList FindIntersection(LinkList L1,LinkList L2){
LinkList L3=Init_List(); //创建空的结果链表。
LNode *p1=L1->Next,*p2=L2->Next,*p3=L3; //指针初始化
while(p1 && p2){ //循环条件
if(p1->Data == p2->Data ){
LNode *node=(LNode *)malloc(sizeof(LNode));
node->Data=p1->Data; //node为临时结点,存放的是交集元素的值
p3->Next=node;
node->Next=NULL;
p3=p3->Next;
p1=p1->Next;
p2=p2->Next;
}
else if(p1->Data>p2->Data){
if(p1->Data>p2->Data) p2=p2->Next;
}
else{
if(p2->Data>p1->Data) p1=p1->Next;
}
}
return L3;
}
int main()
{
LinkList L1=CreateList();
LinkList L2=CreateList();
/* for(LNode *p=L1->Next;p;p=p->Next) printf("%d ",p->Data);
printf("\n");
for(LNode *p=L2->Next;p;p=p->Next) printf("%d ",p->Data);
printf("\n"); */
LinkList L3=FindIntersection(L1,L2);
if(L3->Next==NULL){
printf("NULL\n");
}
else{
L3=L3->Next;
printf("%d",L3->Data);
for(LNode *p=L3->Next;p;p=p->Next) printf(" %d",p->Data);
}
return 0;
}
后记:这里其实有一个小问题,因为文中说的是非降序序列,但是如果输入两个链表有多个相同字母存在则会导致结果链表有重复元素。具体修改欢迎各位读者发表意见。