单链表实现集合交并补

代码部分有参考
#include <stdio.h>
#include <stdlib.h>
#define ERROR -1
#define OK 1
typedef int Status; //要加分号
typedef int ElemType;
typedef struct LNode
{
    ElemType data;
    struct LNode *next;
} LNode, *LinkList;
//创建空链表
Status Init_LinkList(LinkList &L)
{
    LinkList p;
    p = (LinkList)malloc(sizeof(LNode));
    if (!p)
        return ERROR;
    L = p;
    L->next = NULL;
    return OK;
}
int x, y;
void show()
{

    printf("\t\t*********单链表的集合运算************\n");
    printf("\n");
    printf("\t\t\t1. 集合A数据输入\n");
    printf("\t\t\t2. 集合B数据输入\n");
    printf("\t\t\t3. 集合A和集合B的并集\n");
    printf("\t\t\t4. 集合A和集合B的交集\n");
    printf("\t\t\t5. 集合A和集合B的差集\n");
    printf("\t\t\t0. 退出系统\n");
    printf("\n");
    printf("\t\t*********单链表的集合运算*************\n");
    printf("\n");
}
// 输入
Status input(LinkList &L, int n)
{
    LinkList p, tc;
    int i;
    tc = L;
    printf("请输入元素:\n");
    for (i = 1; i <= n; i++)
    {
        p = (LinkList)malloc(sizeof(LNode));
        if (p != NULL)
        {
            scanf("%d", &p->data);
            p->next = L->next; //头插法
            tc->next = p;
            tc = p;
        }

        else
            return ERROR;
    }
    tc->next = NULL;
    printf("集合输入完成!\n");
    return OK;
}

//输出

void Output(LinkList L)
{
    LinkList p; //定义一个指针p
    //p=(LinkList)malloc(sizeof(LNode));
    if (L->next == NULL)
        printf("该链表是空链表!\n");
    else
    {
        for (p = L->next; p != NULL; p = p->next)
            printf("%d ", p->data);
        printf("\n");
    }
}

//实现链表的清空
Status ClearList_L(LinkList &L)
{
    LinkList p, q; //定义两个指针p,q
    p = L->next;
    if (!p) //如果p指向的链表L是一个空表 就直接返回OK
        return OK;
    while (p) //当p指向的链表L不是空表  则进行以下语句,赋给另外一个指针
    {
        q = p;
        p = p->next;
        free(q); //释放链表结点的空间
    }
    L->next = NULL; //将L链表的next指针域 置为 NULL 空
    return OK;
}

//并集  (先清空C,C中的数据会在后面的循环中不断插入!就是A与C找比较,C中没有A的就插入;B与C找比较,C中没有B的就插入(遍历完,即==NULL的时候插入))
void bingji(LinkList La, LinkList Lb, LinkList &Lc)
{
    if (Lc->next != NULL) //如果Lc链表不为空则就要进行链表清空
        ClearList_L(Lc);
    LinkList p, q, s; //p指针用来遍历A,B   q用来控制C的结点

    //对链表A插入C中
    p = La->next; //指针p控制扫描La的每一个结点(元素)
    while (p)

    {
        q = Lc->next;
        while (q && (q->data != p->data)) //C中不为空,且数据不相等时,向下继续进行
            q = q->next;
        if (q == NULL) //当q遍历完一次都没有找到的话,即q的最后为空时就可以将A中的一个元素插入C中
        {
            s = (LinkList)malloc(sizeof(LNode)); //s指针用来控制C中的数据
            s->data = p->data;                   //头插法
            s->next = Lc->next;
            Lc->next = s;
        }
        p = p->next;
    }

    //对链表B插入C中
    p = Lb->next; //指针p控制扫描Lb的每一个结点(元素)
    while (p)
    {
        q = Lc->next;
        while (q && (q->data != p->data)) //C中不为空,且数据不相等
            q = q->next;
        if (q == NULL) //当q遍历完一次都没有找到的话,即q的最后为空时就可以将B中的一个元素插入C中
        {
            s = (LinkList)malloc(sizeof(LNode)); //s指针用来控制C中的数据
            s->data = p->data;                   //头插法
            s->next = Lc->next;
            Lc->next = s;
        }
        p = p->next;
    }
}

//交集   (先清空C链表,再A与B中找相同的break(不为空,记录),再与C中比较(与并集同理插入)插入C中即可)
void jiaoji(LinkList La, LinkList Lb, LinkList &Lc)
{
    LinkList p, q, s, k; //p遍历A,q遍历B,s遍历C,k是赋值指针
    if (Lc->next)
        ClearList_L(Lc);
    //A
    p = La->next;
    while (p) //A中不为空时
    {
        q = Lb->next;
        while (q)
        {
            if (p->data == q->data) //找到了就可以break,也可以定义t进行计数操作,但是这样不好计算链表长度,当然也可以定义全局变量
                break;
            else
                q = q->next;
        }
        if (q) //p不为空
        {
            s = Lc->next;
            //寻找C中是否含有相同数据
            while (s)
            {
                if (s->data == p->data)
                    break;
                else
                    s = s->next;
            }
            if (s == NULL)
            {
                k = (LinkList)malloc(sizeof(LNode));
                k->data = p->data;
                k->next = Lc->next;
                Lc->next = k;
            }
        }
        p = p->next;
    }
}

//差集  (先清空C后,找A中与B中不同的,找到B最后,即==NULL的时候插入即可!)
void chaji(LinkList La, LinkList Lb, LinkList &Lc)
{
    LinkList p, q, s, k;
    if (Lc->next)
        ClearList_L(Lc);
    p = La->next;
    while (p != NULL)
    {
        q = Lb->next;
        while (q != NULL)
        {
            if (q->data == p->data)
                break;
            else
                q = q->next;
        }
        if (q == NULL)
        {
            s = Lc->next;
            //寻找C中是否含有相同数据
            while (s != NULL)
            {
                if (s->data == p->data)
                    break;
                else
                    s = s->next;
            }
            if (s == NULL)
            {
                k = (LinkList)malloc(sizeof(LNode));
                k->data = p->data;
                k->next = Lc->next;
                Lc->next = k;
            }
        }
        p = p->next;
    }
}
int main()
{
    //定义
    int choice;
    LinkList La, Lb, Lc;
    //初始化
    Init_LinkList(La);
    Init_LinkList(Lb);
    Init_LinkList(Lc);
    //功能
    while (1)
    {
        show();
        printf("请输入要选择的功能:\n");
        scanf("%d", &choice);

        switch (choice)
        {
        case 1:
            ClearList_L(La);
            printf("请输入集合A要插入的个数:\n");
            scanf("%d", &x);
            input(La, x);
            printf("集合A为:\n");
            Output(La);
            getchar();
            getchar();
            break;
        case 2:
          ClearList_L(Lb);
            printf("请输入集合B要插入的个数:\n");
            scanf("%d", &y);
            input(Lb, y);
            printf("集合B为:\n");
            Output(Lb);
            printf("请按回车继续!\n");
            getchar();
            getchar();
            break;
          
        case 3:
            printf("集合A与集合B的并集为:\n");
            bingji(La, Lb, Lc);
            Output(Lc);
            printf("请按回车继续!\n");
            getchar();
            getchar();
            break;
        case 4:
            printf("集合A与集合B的交集为:\n");
            jiaoji(La, Lb, Lc);
            Output(Lc);
            printf("请按回车继续!\n");
            getchar();
            getchar();
            break;
        case 5:
            printf("集合A与集合B的并集为:\n");
            chaji(La, Lb, Lc);
            Output(Lc);
            printf("请按回车继续!\n");
            getchar();
            getchar();
            break;
        case 0:
            printf("成功退出系统!\n");
            exit(0);
            getchar();
            getchar();
            break;
        default:
            printf("输入有误!\n");
            exit(0);
            break;
        }
    }
    return 0;
}

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

i want to舞动乾坤

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值