以单链表存储的两个集合求交集的算法

来源:互联网 发布:linux vi e45 编辑:程序博客网 时间:2024/05/18 01:43

原题:设计以单链表存储的两个集合求交集的算法,即设la,lb是两个带头结点的单链表,分别表示两个集合A和B,求它们的交集。


方法1:用单链表lc表示集合C,分别将集合la中元素取出,再在lb中查找,如果lb中出现,则将其插入到lc中。

void interaction(LinkList la,LinkList lb,LinkList &lc){LinkList pa,pb,pc;lc=new LNode;pc=lc;pa=la->next;while(pa){pb=pb->next;while(pb&&pb->data!=pa->data)pb=pb->next;if(pb){pc->next=new LNode;pc=pc->next;pc->data=pa->data;}pa=pa->next;}pc-next=NULL;}


方法2:也可先对la和lb进行排序,再依次比较其中的元素,将相同的元素插入到lc中。

void interaction(LinkList la,LinkList lb,LinkList &lc){LinkList pa,pb,pc;lc=new LNode;pc=lc;sort(la);sort(lb);//对la和lb排序pa=la->next;pb=lb->next;while(pa&&pb){if(pa->data<pb->data)pa=pa->next;else if(pa->data>pb->data)pb=pb->next;else{pc->next=new LNode;pc=pc->next;pc->data=pa->data;pa=pa->next;pb=pb->next;}}pc->next=NULL;}

下面是采用方法2的具体实现程序(先对la和lb进行排序,再依次比较其中的元素,将相同的元素插入到lc中。求交集算法由LNode *Interaction()函数实现。)

#include<stdio.h>#include<stdlib.h>#include<malloc.h>      #include<conio.h>#include<time.h>struct LinkList    //表结点定义{int data;LinkList *next;};struct LNode //头结点定义{LinkList *next;};LinkList *head;//定义分局变量LNode *hp=NULL;//定义全局变量int static flag=1;int DisplayList(LNode *head)//输出链表中的数据域的值{if(head->next==NULL){printf("链表为空!\n");return 0;}LinkList *p;p=head->next;while(p->next!=NULL){printf("%5d ->",p->data);p=p->next;}printf("%5d",p->data);//输出最后一个数据printf("\n");return 0;}LNode *Create()//生成链表的函数定义{int i=0;LinkList *p=NULL;LinkList *q=NULL;head=NULL;if(0 == flag){srand( (unsigned)time( NULL ) );flag=1;}else{flag=0;}for(i=0;i<10;i++){p=(LinkList *)malloc(sizeof(LinkList));p->data=rand()%100*7;if(head==NULL)head=p;elseq->next=p;q=p;}if(head!=NULL){q->next=NULL;}hp=(LNode *)malloc(sizeof(LNode));hp->next=head;return(hp);}LNode *ListSort(LNode *head)//对链表进行自小到大的排序{if(head->next==NULL || head->next->next==NULL)//链表为空或只有一个非头结点时直接返回{return head;}else{LinkList *pre,*lp,*p,*q,*s;pre=head->next;q=p=pre->next;pre->next=NULL;while(p!=NULL){s=(LinkList *)malloc(sizeof(LinkList));s->data=q->data;s->next=NULL;p=p->next;free(q);q=p;//记得释放原结点if(s->data < head->next->data){s->next=head->next;head->next=s;}else{pre=head->next;lp=pre->next;while(lp!=NULL && s->data > lp->data)if(s->data > lp->data){pre=lp;lp=lp->next;}s->next=lp;pre->next=s;}}return head;}}LNode *DelrepetElem(LNode *head)//删除链表中重复的结点{if(head->next!=NULL)//注意如果链表为空(即只有头结点而没有数据结点的情况下)不做些判断,                {//就执行以下代码将出现非法访问内存的错误LinkList *pre=head->next,*lp;if(pre->next!=NULL){while(pre->next!=NULL)if(pre->data != pre->next->data)pre=pre->next;else{lp=pre->next;pre->next=lp->next;free(lp);}}}return head;}LNode *Interaction(LNode *headla,LNode *headlb){LinkList *pa,*pb,*pc;//用全局变量hp来做lc的头结点时出错?原因未知,所以在此不用LNode *lc=(LNode *)malloc(sizeof(LNode));lc->next=NULL;if(headla->next!=NULL && headlb->next!=NULL){pa=headla->next;pb=headlb->next;while(pa!=NULL && pb!=NULL){if(pa->data < pb->data)pa=pa->next;else if(pa->data > pb->data)pb=pb->next;else//采用头插法生成交集链表{pc=(LinkList *)malloc(sizeof(LinkList));pc->data=pa->data;pc->next=lc->next;lc->next=pc;pa=pa->next;pb=pb->next;}}return lc;}return lc;//如果两链表中有一个或两个为空,则直接返回}void main(){LNode *headla,*headlb,*headlc;headla=Create();//生成链表laheadla=ListSort(headla);headla=DelrepetElem(headla);printf("经排序且删除相同元素后的链表la的数据为:\n");DisplayList(headla);headlb=Create();//生成链表lbheadlb=ListSort(headlb);headlb=DelrepetElem(headlb);printf("经排序且删除相同元素后的链表lb的数据为:\n");DisplayList(headlb);headlc=Interaction(headla,headlb);headlc=ListSort(headlc);//重排序printf("链表la与链表lb的交集为:\n");DisplayList(headlc);}


 

 

 

原创粉丝点击