基於單鏈表實現集合的交集、並集、差集的運算


解題思路(單鏈表求交集、並集、差集的思想和順序表求交集、並集、差集的思想基本相同)

1.先通過CreateListR 函數將集合 a 和 b 中的元素添加到順序表 ha 和 hb 中 ,添加過程使用的是順序表原有的Initlist 函數(初始化表) 和 ListInsert 函數 (向表中插入元素)  。

2.因為原集合是無序的, 所以我通過 sort 函數 (選擇排序),使得集合變得有序。

3.得到有序集合 ha 和 hb 后, 便可以使用 Union 函數(類似歸並的思想寫出來的求並集的函數),求出 ha 和 hb 的並集。

4.而求交集的方法則是, 通過將 集合 a 中的元素一個一個取出,並通過 函數LocateElem ,查看集合 hb 中是否存在該元素,如果存在則將 元素放入 hc ,如果不存在,則舍去。 以此求得 兩 集合的交集。

5.求兩集合的差 則可以反過來,同樣通過將 集合 a 中的元素一個一個取出,並通過 函數LocateElem ,查看集合 hb 中是否存在該元素,如果不存在則將 元素放入 hc ,如果存在,則舍去。 以此求得兩集合的差集。

#include <iostream>
#include <cstdio>
#include <malloc.h>
using namespace std;

/* 定義單鏈表數據 */
typedef char ElemType;
typedef struct LNode
{
    ElemType data;
    struct LNode *next;
}LinkList;

/* 單鏈表的初始化 */
void InitList(LinkList *&L)
{
    L = (LinkList *)malloc(sizeof(LinkList));
    L->next=NULL;
}

/* 向單鏈表中插入數據元素 */
bool ListInsert(LinkList *&L,int x,char e)
{
    int j = 0;
    LinkList *p = L, *s;
    while(p!=NULL && j<x-1)
    {
        p = p->next;
        j++;
    }
    if(p==NULL)
    {
        return false;
    }
    else
    {
        s = (LinkList *)malloc(sizeof(LinkList));
        s->data = e;
        s->next = p->next;
        p->next = s;
        return true;
    }
}

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

/* 求單鏈表的長度 */
int ListLength(LinkList *L)
{
    LinkList *p = L->next;
    int i = 0;
    while(p!=NULL)
    {
        i++;
        p = p->next;
    }
    return i;
}

/* 查看單鏈表是否為空 */
bool ListEmpty(LinkList *L)
{
    return L->next==NULL;
}

/* 求單鏈表中某個數據元素值 */
bool GetElem(LinkList *L,int i, ElemType &e)
{
    LinkList *p = L;
    int j = 0;
    while(p!=NULL && j < i)
    {
        p=p->next;
        j++;
    }
    if(p==NULL)
    {
        return false;
    }
    else
    {
        e = p->data;
        return true;
    }
}

/* 在單鏈表中查找元素 */
int LocateElem(LinkList *L,ElemType e)
{
    LinkList *p = L;
    int i = 0;
    while(p!=NULL && p->data!=e)
    {
        p = p->next;
        i++;
    }
    if(p==NULL)
    {
        return 0;
    }
    else
    {
        return i;
    }
}

/* 刪除單鏈表中第 i 個元素*/
bool ListDelete(LinkList *&L,int i,ElemType &e)
{
    int j = 0;
    LinkList *p = L, *q;
    while(p!=NULL && j < i - 1)
    {
        p = p->next;
        j++;
    }
    if(p==NULL)
        return false;
    else
    {
        q = p->next;
        if(q==NULL)
            return false;
        e = q->data;
        p->next = q->next;
        free(q);
        return true;
    }
}

/* 刪除單鏈表 */
void DestroyList(LinkList *&L)
{
    LinkList *p = L;
    LinkList *q = p->next;
    while(q!=NULL)
    {
        free(p);
        p = q;
        q = p->next;
    }
    free(p);
}

void CreateListR(LinkList *&L,ElemType e[],int n)
{
    InitList(L);
    int i;
    for(i = 0;i < n; ++i)
    {
        if(!LocateElem(L,e[i]))
            ListInsert(L,i+1,e[i]);
    }
}

void InsterSect(LinkList *a,LinkList *b,LinkList *&c)
{
    DestroyList(c);
    InitList(c);
    LinkList *p = a->next;
    int i = 0;
    while(p!=NULL)
    {
        if(LocateElem(b,p->data))
            ListInsert(c,++i,p->data);
        p = p->next;
    }
}

void Subs(LinkList *a,LinkList *b,LinkList *&c)
{
    DestroyList(c);
    InitList(c);
    LinkList *p = a->next;
    int i = 0;
    while(p!=NULL)
    {
        if(!LocateElem(b,p->data))
            ListInsert(c,++i,p->data);
        p = p->next;
    }
}

void Union(LinkList *a,LinkList *b,LinkList *&c)
{
    InitList(c);
    LinkList *p = a->next;
    LinkList *q = b->next;
    int k = 0;
    while(p!=NULL && q!=NULL)
    {
        if(p->data < q->data)
        {
            ListInsert(c,k+1,p->data);
            p = p->next;
            k++;
        }
        else if(p->data == q->data)
        {
            ListInsert(c,k+1,p->data);
            p = p->next;
            q = q->next;
            k++;
        }
        else
        {
            ListInsert(c,k+1,q->data);
            q = q->next;
            k++;
        }
    }
    while(p!=NULL)
    {
        ListInsert(c,k+1,p->data);
        p = p->next;
        k++;
    }
    while(q!=NULL)
    {
        ListInsert(c,k+1,q->data);
        q  = q->next;
        k++;
    }
    ///cout<<"hehe"<<endl;
}

void sort(LinkList *&L)
{
    LinkList *p , *pre, *q, *k;
    InitList(p);
    int i = 0;
    char c;
    while(!ListEmpty(L))
    {
        pre = L ->next;
        c = pre->data;
        while(pre!=NULL)
        {
            if(c>=pre->data)
                c = pre->data;
            pre = pre->next;
        }
        ListInsert(p,++i,c);
        int tag = LocateElem(L,c);
        ListDelete(L,tag,c);
    }
    L = p;
}


int main( )
{
    LinkList *ha, *hb, *hc;
    ElemType a[]={'c','a','e','h'};
    ElemType b[]={'f','h','b','g','d','a'};
    printf("集合的運算如下\n");
    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);
    InsterSect(ha,hb,hc);
    printf("集合的交C:"); DispList(hc);
    Subs(ha,hb,hc);
    printf("集合的差C:"); DispList(hc);
    DestroyList(ha);
    DestroyList(hb);
    DestroyList(hc);
    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM