zoukankan      html  css  js  c++  java
  • 集合抽象数据类型的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);
    }
  • 相关阅读:
    OpenGL纹理映射总结
    研究生常用网站:
    Oracle 11g,10g数据库软件下载地址
    <转>乔布斯羡慕嫉妒恨的人:Android之父安迪·鲁宾
    VC6里面的中文名字或者注释复制乱码解决
    基于CentOs的Hadoop集群全分布式部署<转>
    centos架设FTP服务器
    centos 卸载 jdk
    ESX的 企业版许可证
    vsftpd的 553 Could not create file
  • 原文地址:https://www.cnblogs.com/idreamo/p/7907334.html
Copyright © 2011-2022 走看看