求集合(用有序单链表表示)的并/交和差运算

#include <stdio.h>
#include <malloc.h>

typedef char ElemType;
typedef struct LNode                        // 定义单链表结点类型
{
    ElemType data;                            // 数据域
    struct LNode *next;                        // 指向后继结点
}LinkList;


/*-------------------------输出单链表L----------------------------*/
void DispList(LinkList *L)
{
    LinkList *p = L->next;
    
    while(p != NULL)
    {
        printf("%c ", p->data);
        p = p->next;
    }
    printf("\n");
}

/*-------------------------尾部插入法建表----------------------------*/
void CreateListR(LinkList *&L, ElemType a[], int n)    // 指针的引用
{
    int i;
    LinkList *s, *r;
    
    L = (LinkList *)malloc(sizeof(LinkList));                    // 创建头结点
    L->next = NULL;
    r = L;                                                        // r始终指向终端结点,开始时指向头结点
    for(i = 0; i < n; i++)
    {
        s = (LinkList *)malloc(sizeof(LinkList));                // 创建新结点
        s->data = a[i];
        r->next = s;                                            // 将s插入到r之后
        r = s;
    }
    r->next = NULL;                                                // 终端结点next域设置为NULL
}

/*-------------------------单链表元素排序----------------------------*/
void Sort(LinkList *&head)
{
    LinkList *p = head->next, *q, *r;
    
    if(p != NULL)                                                // 若原单链表中有一个或以上的数据结点
    {
        r = p->next;                                            // r指向p结点的后继结点
        p->next = NULL;                                            // 构造只含一个数据结点的有序表
        p = r;
        while(p != NULL)
        {
            r = p->next;                                        // r指向p结点的后继结点
            q = head;
            while((q->next != NULL) && (q->next->data < p->data))
                q = q->next;
            // 将p插入到q之后
            p->next = q->next;
            q->next = p;
            p = r;
        }
    }
}

/*-------------------------求两个有序集合的并----------------------------*/
void Union(LinkList *ha, LinkList *hb, LinkList *&hc)
{
    LinkList *pa = ha->next;                                // pa指向集合ha中的第一个数据结点
    LinkList *pb = hb->next;                                // pb指向集合hb中的第一个数据结点
    LinkList *s;
    LinkList *tc;
    
    hc = (LinkList *)malloc(sizeof(LinkList));                // 创建头结点
    tc = hc;
    while((pa != NULL) && (pb != NULL))
    {
        if(pa->data < pb->data)
        {
            s = (LinkList *)malloc(sizeof(LinkList));        // 复制结点
            s->data = pa->data;
            tc->next = s;
            tc = s;
            pa = pa->next;
        }
        else if(pa->data > pb->data)
        {
            s = (LinkList *)malloc(sizeof(LinkList));        // 复制结点
            s->data = pb->data;
            tc->next = s;
            tc = s;
            pb = pb->next;
        }
        else
        {
            s = (LinkList *)malloc(sizeof(LinkList));        // 复制结点
            s->data = pa->data;
            tc->next = s;
            tc = s;
            pa = pa->next;                                    // 重复的元素只复制一个
            pb = pb->next;
        }
    }
    if(pb != NULL)
        pa = pb;
    while(pa != NULL)
    {
        s = (LinkList *)malloc(sizeof(LinkList));        // 复制结点
        s->data = pa->data;
        tc->next = s;
        tc = s;
        pa = pa->next;    
    }
    tc->next = NULL;
}

/*-------------------------求两个有序集合的交----------------------------*/
void InterSect(LinkList *ha, LinkList *hb, LinkList *&hc)
{
    LinkList *pa = ha->next;                            // pa指向集合ha中的第一个数据结点
    LinkList *pb, *s, *tc;
    
    hc = (LinkList *)malloc(sizeof(LinkList));            // 创建头结点
    tc = hc;
    while(pa != NULL)
    {
        pb = hb->next;                                    
        while((pb != NULL) && (pb->data < pa->data))
            pb = pb->next;
        if((pb != NULL) && (pb->data == pa->data))        // 若pa结点值在B中
        {
            s = (LinkList *)malloc(sizeof(LinkList));    // 复制结点
            s->data = pa->data;
            tc->next = s;
            tc = s;
        }
        pa = pa->next;
    }
    tc->next = NULL;
}

/*-------------------------求两个有序集合的差----------------------------*/
void Subs(LinkList *ha, LinkList *hb, LinkList *&hc)
{
    LinkList *pa = ha->next;                            // pa指向集合ha中的第一个数据结点
    LinkList *pb, *s, *tc;
    
    hc = (LinkList *)malloc(sizeof(LinkList));            // 创建头结点
    tc = hc;
    while(pa != NULL)
    {
        pb = hb->next;    
        while((pb != NULL) && (pb->data < pa->data))
            pb = pb->next;
        if(!(pb != NULL && pb->data == pa->data))        // 若pa结点值不在B中
        {
            s = (LinkList *)malloc(sizeof(LinkList));    // 复制结点
            s->data = pa->data;
            tc->next = s;
            tc = s;
        }
        pa = pa->next;
    }
    tc->next = NULL;
}

int main(void)
{
    LinkList *ha, *hb, *hc;
    ElemType a[] = {'c', 'a', 'e', 'h'};
    ElemType b[] = {'f', 'h', 'b', 'g', 'd', 'a'};

    CreateListR(ha, a, 4);
    CreateListR(hb, b, 6);
    printf("原集合A:");
    DispList(ha);
    printf("原集合B:");
    DispList(hb);
    Sort(ha);
    Sort(hb);
    printf("有序集合A:");
    DispList(ha);
    printf("有序集合B:");
    DispList(hb);
    Union(ha, hb, hc);
    printf("集合的并C:");
    DispList(hc);
    InterSect(ha, hb, hc);
    printf("集合的交C:");
    DispList(hc);
    Subs(ha, hb, hc);
    printf("集合的差C:");
    DispList(hc);

    return 0;
}

测试结果:

原集合A:c a e h
原集合B:f h b g d a
有序集合A:a c e h
有序集合B:a b d f g h
集合的并C:a b c d e f g h
集合的交C:a h
集合的差C:c e

  • 7
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值