单链表简单应用之求集合的交并集

C语言单链表应用之求集合的交并集

本篇文章讲述了如何应用数据结构中的单链表求集合的交并集。思想很简单,建议大家在看这篇博客之前可以先熟悉下用单链表实现两个有序链表的归并。


前言

为了方便,本篇文章就以整型数据为例,如果数据是字符型,一定要注意处理空格。

一、集合的交并集

比如有两个集合A={1,3,5,7},集合B={3,9}。
那么这两个集合的交集是{3},两个集合的并集是{1,3,5,7,9}。

二、算法步骤

1.求并集的函数模块

  1. 设标志位flag初始值为0。
  2. 先用循环语句将集合A中的元素复制到并集集合,即单链表C中。
  3. 再以此判定集合B中的元素是否在集合A中,若存在,置flag=1。
  4. 当flag=1时,则说明当前B中元素不与A中任何元素相等,将B中此元素用尾插法插入到并集集合C中。
  5. 集合B中当前元素判断完成后,置标志位flag回到初始值为0,为B中下一个元素判断是否与A中元素相同做准备。
void Union(LinkList L1,LinkList L2,LinkList *L3)
{
    LinkList p,q,r,s;
    int flag=0;
    r=*L3;
    //将集合L1都赋值到L3中去
    for(p=L1->next;p!=NULL;p=p->next)
    {
        s=(LinkList)malloc(sizeof(LNode));
        s->data=p->data;
        r->next=s;  
        r=s;
        s->next=NULL;
    }
    for(p=L2->next;p!=NULL;p=p->next)
    {
        for(q=L1->next;q!=NULL;q=q->next)
        {
            if(p->data==q->data)
            {
                flag=1;
                break;
            }
        }
        if(flag==0)//说明集合B中有集合A中没有的元素,此时尾插法插入到集合A中
        {
            s=(LinkList)malloc(sizeof(LNode));
            s->data=p->data;
            r->next=s;
            r=s;
        }
        flag=0;//重置标志位
    }
	r->next=NULL;
}

2.求交集的函数模块

  1. 与求并集相类似,利用双重循环,使集合A中一个元素与集合B中所有元素比较,存在相等的元素,用尾插法将该元素插入到交集集合的链表C中,对集合A中所有元素依次重复上述操作,即得到集合A和集合B的交集C。
//reg:标志位,当reg=0时,说明无交集,为1说明有交集
int InterLinkCollection(LinkList L1,LinkList L2,LinkList *L3)
{
    LinkList p,q,r,s;
    int reg=0;
    r=*L3;
    for(p=L1->next;p!=NULL;p=p->next)
    {
        for(q=L2->next;q!=NULL;q=q->next)
        {
            if(p->data==q->data)
            {
                s=(LinkList)malloc(sizeof(LNode));
                s->data=p->data;
                r->next=s;
                r=s;
                reg=1;
            }
        }
    }
	r->next=NULL;
    return reg;
}

三、完整代码

/**
 * 下面是单链表的应用,集合的交并集
 */
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>

typedef struct LNode
{
    char data;
    struct LNode *next;
}LNode,*LinkList;

//创建头结点
void InitList(LinkList *L)
{
    *L=(LinkList)malloc(sizeof(LNode));
    if(!*L)
    {
        printf("内存分配失败!\n");
        exit(0);
    }
    (*L)->next=NULL;
}

//尾插法创建链表
void CreatList_Tail(LinkList *L)
{
    LinkList r,s;
    r=*L;
    char ch;
    scanf("%c",&ch);
    while (ch!='$')
    {
        s=(LinkList)malloc(sizeof(LNode));
        s->data=ch;
        r->next=s;
        r=s;
        scanf("%c",&ch);
    }
    r->next=NULL;
}

void DipList(LinkList L)
{
    LinkList p;
    p=L->next;
    while(p!=NULL)
    {
        printf("%c ",p->data);
        p=p->next;
    }
}

//集合的并运算
void Union(LinkList L1,LinkList L2,LinkList *L3)
{
    LinkList p,q,r,s;
    int flag=0;
    r=*L3;
    //将集合L1都赋值到L3中去
    for(p=L1->next;p!=NULL;p=p->next)
    {
        s=(LinkList)malloc(sizeof(LNode));
        s->data=p->data;
        r->next=s;  
        r=s;
        s->next=NULL;
    }
    for(p=L2->next;p!=NULL;p=p->next)
    {
        for(q=L1->next;q!=NULL;q=q->next)
        {
            if(p->data==q->data)
            {
                flag=1;
                break;
            }
        }
        if(flag==0)//说明集合B中有集合A中没有的元素,此时尾插法插入到集合A中
        {
            s=(LinkList)malloc(sizeof(LNode));
            s->data=p->data;
            r->next=s;
            r=s;
        }
        flag=0;//重置标志位
    }
	r->next=NULL;
}


int InterLinkCollection(LinkList L1,LinkList L2,LinkList *L3)
{
    LinkList p,q,r,s;
    int reg=0;
    r=*L3;
    for(p=L1->next;p!=NULL;p=p->next)
    {
        for(q=L2->next;q!=NULL;q=q->next)
        {
            if(p->data==q->data)
            {
                s=(LinkList)malloc(sizeof(LNode));
                s->data=p->data;
                r->next=s;
                r=s;
                reg=1;
            }
        }
    }
	r->next=NULL;
    return reg;
}



int main()
{
    LinkList L1,L2,L3,L4;
    int j;

    InitList(&L1);
    InitList(&L2);
    InitList(&L3);
	InitList(&L4);
    CreatList_Tail(&L1);
	getchar();
    CreatList_Tail(&L2);
    Union(L1,L2,&L3);
    DipList(L3);
	printf("\n");

    j=InterLinkCollection(L1,L2,&L4);
	if(j==0)
		printf("无交集\n");
	else
		DipList(L4);
	printf("\n");
    return 0;
}
  • 2
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值