6-3【李春葆教材】(必做) 集合的基本运算(单链表) (20分)

写在前面:这是一道为了巩固知识的题目,又坑又多,稍一走神就会写错,导致断言错误(我目前接触到的断言错误都是因为出现野指针)
有两个字符集合A和B,现在要求实现集合的并、交、差运算。 要求:集合用单链表表示,假设同一个集合中不存在重复的元素。A、B集合元素最多不超过100个,至少有一个元素。 算法实现: 1)将两个集合的元素按递增方式排序,构成有序单链表。 2)采用二路归并算法求集合的并集、交集和差集。

链表结构及操作函数接口定义:
typedef char ElemType;
typedef struct LNode //定义单链表结点类型
{
ElemType data;
struct LNode *next;
} LinkList;
void DispList(LinkList *L); //输出链表元素,每个结点元素值以空格符间隔,以换行符结束。
void CreateListR(LinkList *&L,ElemType a[],int n); //用数组元素值尾插法创建链表。
void DestroyList(LinkList *&L);//销毁链表。
void sort(LinkList *&L) //单链表元素递增排序。
void Union(LinkList *ha,LinkList *hb,LinkList *&hc) //求两有序集合ha、hb的并集hc。
void InterSect(LinkList *ha,LinkList *hb,LinkList *&hc) //求两有序集合ha、hb的的交集hc。
void Subs(LinkList *ha,LinkList *hb,LinkList *&hc) //求两有序集合ha、hb的差集hc。

裁判测试程序样例:
#include <stdio.h>
#include <malloc.h>
int main()
{
LinkList *ha,*hb,*hc;
ElemType a[100]={0};
ElemType b[100]={0};
int i=0;
char ch;
while((ch=getchar())!=’\n’)
{
a[i++]=ch;
}
CreateListR(ha,a,i);
i=0;
while((ch=getchar())!=’\n’)
{
b[i++]=ch;
}
CreateListR(hb,b,i);
printf("A: ");DispList(ha);
printf("B: ");DispList(hb);
sort(ha);
sort(hb);
printf("sorted A: ");DispList(ha);
printf("sorted B: ");DispList(hb);
Union(ha,hb,hc);
printf("Union C: ");DispList(hc);
InterSect(ha,hb,hc);
printf("InterSect C: ");DispList(hc);
Subs(ha,hb,hc);
printf("Subs C: ");DispList(hc);
DestroyList(ha);
DestroyList(hb);
DestroyList(hc);
return 0;
}

/* 请在这里填写答案 */

输入样例:
在这里给出一组输入。例如:

adecfgvjkz
akidqe

输出样例:
在这里给出相应的输出。例如:

A: a d e c f g v j k z
B: a k i d q e
sorted A: a c d e f g j k v z
sorted B: a d e i k q
Union C: a c d e f g i j k q v z
InterSect C: a d e k
Subs C: c f g j v z

作者: 张庆
单位: 集美大学
时间限制: 400 ms
内存限制: 64 MB

void DispList(LinkList* L) //输出链表元素,每个结点元素值以空格符间隔,以换行符结束。
{
    LinkList* p;
    for (p = L->next; p; p = p->next)printf("%c ", p->data);
    printf("\n");
}
void CreateListR(LinkList*& L, ElemType a[], int n)//用数组元素值尾插法创建链表。
{
    L = (LinkList*)malloc(sizeof(struct LNode));
    L->next = NULL;
    LinkList* p, * q;
    q = L;
    for (int i = 0; i < n; i++) {
        p = (LinkList*)malloc(sizeof(struct LNode));
        p->data = a[i];
        q->next = p;
        q = p;
    }
    q->next = NULL;
}
void DestroyList(LinkList*& L)//销毁链表。
{
    if (L == NULL)return;
    LinkList* p, * q;
    p = L; q = L->next;
    while (q) {
        free(p);
        p = q;
        q = p->next;
    }
    free(p);
}
void sort(LinkList*& L)		//单链表元素递增排序。
{
    LinkList* p, * q, * pre;
    q = L->next->next;
    L->next->next = NULL;//
    while (q) {
        p = q->next;//标记下一个位置
        pre = L;
        while (pre->next != NULL && pre->next->data < q->data) {
            pre = pre->next;
        }
        q->next = pre->next;
        pre->next = q;
        q = p;
    }

}
void Union(LinkList* ha, LinkList* hb, LinkList*& hc)  //求两有序集合ha、hb的并集hc。
{
    LinkList* la, * lb, * lc,*p;
    hc = (LinkList*)malloc(sizeof(struct LNode));
    hc->next = NULL;
    lc = hc;
    la = ha->next; lb = hb->next;
    while (la && lb) {
        if (la->data < lb->data) {
            p = (LinkList*)malloc(sizeof(struct LNode));
            p->data = la->data;
            p->next = NULL;
            lc->next = p; lc = p; la = la->next;
        }
        else if (la->data > lb->data) {
            p = (LinkList*)malloc(sizeof(struct LNode));
            p->data = lb->data;
            p->next = NULL;
            lc->next = p; lc = p; lb = lb->next;
        }
        else {
            p = (LinkList*)malloc(sizeof(struct LNode));
            p->data = la->data;
            p->next = NULL;
            lc->next = p; lc = p;
            la = la->next; lb = lb->next;
        }
    }
    while (la) {
        p = (LinkList*)malloc(sizeof(struct LNode));
        p->data = la->data;
        p->next = NULL;
        lc->next = p; lc = p;
        la = la->next; 

   }
    while (lb) {
        p = (LinkList*)malloc(sizeof(struct LNode));
        p->data = lb->data;
        p->next = NULL;
        lc->next = p; lc = p;
        lb= lb->next;

    }
}
void InterSect(LinkList* ha, LinkList* hb, LinkList*& hc)	//求两有序集合ha、hb的的交集hc。
{
    LinkList* la, * lb, * lc,*p;
    hc = (LinkList*)malloc(sizeof(struct LNode));
    hc->next = NULL;
    lc = hc;
    la = ha->next; lb = hb->next;
    while (la && lb) {
        if (la->data < lb->data) {
             la = la->next;
        }
        else if (la->data > lb->data) {
            lb = lb->next;
        }
        else {
            p = (LinkList*)malloc(sizeof(struct LNode));
            p->data = la->data;
            p->next = NULL;
            lc->next = p; lc = p;
            la = la->next; lb = lb->next;
        }
    }
}
void Subs(LinkList* ha, LinkList* hb, LinkList*& hc)	//求两有序集合ha、hb的差集hc。
{
    LinkList* la, * lb, * lc, * p;
    hc = (LinkList*)malloc(sizeof(struct LNode));
    hc->next = NULL;
    lc = hc;
    la = ha->next; lb = hb->next;

    while (la && lb) {
        if (la->data < lb->data) {
            p = (LinkList*)malloc(sizeof(struct LNode));
            p->data = la->data;
            p->next = NULL;
            lc->next = p; lc = p; la = la->next;
        }
        else if (la->data > lb->data) {
            lb = lb->next;
        }
        else {
            la = la->next; lb = lb->next;
        }
    }
    while (la) {
        p = (LinkList*)malloc(sizeof(struct LNode));
        p->data = la->data;
        p->next = NULL;
        lc->next = p; lc = p;
        la = la->next;

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值