数据结构 集合_集合(数学)抽象数据类型的C语言实现

链表是促成集的同一栽优质的法门。将List以typedef的计重命名为Set。这样做能够保留链表简洁的表征,还会如集合有了有些多态的特性。

采用这种方式的无限老补虽好行使list_next来遍历一个集结,使用list_rem_next来移除一个成员,而并非根据成员所蕴藏的数额来标识它。

咱俩先来查阅转会合抽象数据类型头文件的情节:

演示1:集合(抽象数据类型)头文件

#ifndef SET_H
#define SET_H 

#include <stdlib.h>
#include "list.h"
/*将集合定义成List结构*/
typedef List Set;
/*集合的初始化*/
void set_init(Set *set,int (match*)(const void *key1,const void *key2),void(*destroy)(void *data));
/*集合销毁,定义成链表销毁函数*/
#define set_destroy List_destroy
/*向集合中插入元素*/
int set_insert(Set *set, const void *data);
/*从集合中移除元素*/
int set_remove(Set *set, void **data);
/*求集合的并集*/
int set_union(Set *setu, const Set *set1, const Set *set2);
/*求集合的交集*/
int set_intersection(Set *seti, const Set *set1,const Set *set2);
/*求集合的差集*/
int set_difference(Set *setd, const Set *set1,const Set *set2);
/*判断成员是否属于集合*/
int set_is_member(const Set *set, const void *data);
/*判断子集*/
int set_is_subset(const Set *set1, const Set *set2);
/*判断集合是否相等*/
int set_is_equal(const Set *set1, const Set *set2);
/*集合中元素的个数*/
#define set_size(set) ((set)->size)

#endif

下面是各种操作的切实可行实现:

 示例2:集合抽象数据类型的贯彻

#include <stdlib.h>
#include <string.h>
#include "list.h"
#include "set.h"

/*set_init  初始化一个集合*/
void set_init(Set *set,int(*match)(const void *key1,const void *key2), void(*destroy)(void *data))
{
    /*调用list_init*/
    list_init(set,destroy);
    /*单独初始化match成员*/
    set->match = match;

    return;
}

/*set_insert  向集合中插入一个成员*/
int set_insert(Set *set,const void *data)
{
    /*不能向集合中插入已有成员*/
    if(set_is_member(set,data))
        return -1;
    /*调用list_ins_next插入元素至尾端*/
    return list_ins_next(set,list_tail(set),data);
}

/*set_remove  移除元素*/
int set_remove(Set *set,void **data)
{
    ListElmt *member, *prev;
    /*查找要移除的成员*/
    prev=NULL;
    /*遍历链表*/
    for(member=list_head(set); member != NULL; member = list_next(member))
    {
        if(set->match(*data,(list_data(member)))
            break;
        prev=member;  /*prev刚好指向匹配成功的成员的前一个成员*/
    }

    /*没有找到成员则返回*/
    if(member==NULL)
        return -1;
    /*移除成员*/
    return list_rem_next(set,prev,data);
}

/*set_union 求解两个集合的并集*/
int set_union(Set *setu,const Set *set1,const Set *set2)
{
    ListElmt *member;
    void *data;

    /*初始化一个并集集合*/
    set_init(setu,set1->match,NULL);

    /*将集合1的内容插入并集*/
    for(member=list_head(set1);member!=NULL;member=list_next(member))
    {
        data=list_data(member);
        if(list_ins_next(setu,list_tail(setu),data)!=0)
            {
                set_destroy(setu);
                return -1;
             }
    }

    /*插入集合2的成员*/
    for(member=list_head(set2);member!=NULL;member=list_next(member))
    {
        if(set_is_member(set1,list_data(member)))
        {
            continue;
        }
        else
        {
            data=list_data(member);
            if(list_ins_next(setu,list_tail(setu),data))!=0)
            {
                set_destroy(setu);
                return -1;
            }
        }
    }
    return 0;
}

/*set_intersection  求解两个集合的交集*/
int set_intersection(Set *seti,const Set *set1,const Set *set2)
{
    ListElmt *member;
    void *data;

    /*初始化交集集合*/
    set_init(seti,set1->match,NULL);

    /*同时在两个集合中出现的元素将被插入交集集合中*/
    for(member=list_head(set1);member!=NULL;list_next(member))
    {
        if(set_is_member(set2,list_data(member))
        {
            data=list_data(member);
            if(list_ins_next(seti,list_tail(seti),data))!=0)
            {
                set_destroy(seti);
                return -1;
            {
        }
    }
return 0;
}

/*set_difference  求解两个集合的差集*/
int set_intersection(Set *setd,const Set *set1,const Set *set2)
{
    ListElmt *member;
    void *data;

    /*初始化差集集合*/
    set_init(setd,set1->match,NULL);

    /*不同时在两个集合中出现的元素将被插入差集集合中*/
    for(member=list_head(set1);member!=NULL;list_next(member))
    {
        if( ! set_is_member(set2,list_data(member))
        {
            data=list_data(member);
            if(list_ins_next(setd,list_tail(setd),data))!=0)
            {
                set_destroy(setd);
                return -1;
            {
        }
    }
return 0;
}

/*set_is_member  判断由data指定的成员是否在由set指定的集合中*/
int set_is_member(const Set *set,void *data)
{
    ListElmt *member;

    for(member=list_head(set);member!=NULL;list_next(member))
    {
        if(set->match(data,list_data(member))
        return 1;
    }
    return 0;
}

/*set_is_subset 判断集合set1是否是集合set2的子集*/
int set_is_subset(const Set *set1,const Set *set2)
{
    ListElmt *member;

    /*首先排除集合1成员数量大于集合2成员数量的情况*/
    if(set_size(set1)>set_size(set2))
        return 0;

    /*如果set1的成员不都在set2中,则判断不成立,除此成立*/
    for(member=list_head(set1);member!=NULL;list_next(member))
    {
        if( !set_is_member(set2,list_data(member)))
        {
            return 0;
        }
    }
    return 1;
}

/*set_is_equal  判断两个集合是否相等*/
int set_is_equal(const Set *set1,const Set *set2)
{
    /*首先排除两个集合成员数量不相等的情况*/
    if(set_size(set1) != set_size(set2))
    return 0;

    /*两个集合成员数量相等,且一个集合是另一个集合的子集时,这两个集合相等*/
    return  set_is_subset(set1,set2);
}