C算法精解 ---集合的实现和分析

   前面已经介绍了链表、栈和队列的实现,也了解到在栈和队列的实现过程中,都用到的单链表的函数接口。下面介绍新的:集合。

   集合是不同对象的无序的聚集,集合的2个重要特点就是无序、和无重复性。在高中已经了解集合的很多知识,下面来回忆下,集合的特性。目前正在学习思维导图(本人也想把这个软件推荐给大家使用,软件可以在我的下载界面下载,链接:点击打开链接),下面就花了个文字型的导图,来介绍集合的定义、基本操作及性质。

下面来介绍集合的定义和实现分析

   集合的定义和实现,同样也是用了单链表的函数接口,所有需要的把单链表的函数接口阅读完,再看下面代码的实现。对函数接口的实现就不在分析了,只要认真阅读,肯定能理解!

/*set.h*/
#ifndef SET_H
#define SET_H

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

/* implement sets as linked list */

typedef List Set;

/* public interface */

void set_init(Set *set,int (*match)(const void *key1,const void * key2),
                      void  (*destroy)(void *data));
#define set_destroy list_destory 
int set_insert(Set *set, void * data);
int set_remove(Set *set,void * data);
int set_union(Set *setu,const Set *set1,const Set *set2);
int set_intersection(Set *setu,const Set *set1,const Set *set2);
int set_difference(Set *setu,const Set *set1,const Set *set2);
int set_is_number(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


 

/*set.c */

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

void set_init(Set * set, int(* match)(const void * key1, const void * key2), void(* destroy)(void * data))
{
    /*initialize the set */
    list_init(set, destroy);
    set->match = match;

    return;
}

/*set_insert */
int set_insert(Set * set, void * data)
{
    /*Do not allow the insertion od duplicates */
    if (set_is_number(set, const data)){
        return 1;
    }
    /*insert the set*/
    return list_ins_next(set, list_tail(set), data);
}
/*set_romove */
int set_remove(set * set, void * data){
    ListElmt *member, *prev;
    /*find the member to remove */
    prev = NULL;

    for (member = list_head(set),member != NULL,member = list_next(member)){
         if (set->match(*data,list_data(member)){
            break;
         }
         prev = member;
    }
    /*return if member is NULL*/
    if (NULL == member){
        return -1;
    } else {/*remove the member*/
        return list_rem_next(set, prev, data);
    }
    
}

/* set_union */
int set_union(Set * setu, const Set * set1, const Set * set2){
    ListElmt *member;
    void *data;

    /* initialize the setu */
    set_init(Set * setu, set1->match, NULL);
    /*insert the member of the sirst set*/
    for (member = list_head(set1), member != NULL,list_next(set1)){
         data = list_data(member);
         if (list_ins_next(setu, list_tail(setu), data) != 0){
            set_destroy(setu);
            return -1;
         }
    }

    /*insert the second set2*/
    for ( member = list_head(set2), member != NULL, list_next(set2)){
         if (set_is_number(setu, list_data(set2)){
             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;

    /* initialize the setu */
    set_init(Set * seti, set1->match, NULL);
    /*insert the member of the sirst set*/
    for (member = list_head(set1), member != NULL,list_next(set1)){
         if (set_is_number(setu, list_data(set2)){
             data = list_data(member);
             if (list_ins_next(setu, list_tail(setu), data) != 0){
                set_destroy(setu);
                return -1;
             }
        }
    }
    return 0;
}
/*set_difference */
int set_difference(Set * setu, const Set * set1, const Set * set2){
    ListElmt *member;
    void *data;
    /* initialize the setu */
    set_init(Set * seti, set1->match, NULL);
    /*insert the member of the sirst set*/
    for (member = list_head(set1), member != NULL,list_next(set1)){
         if (!set_is_number(setu, list_data(set2)){
             data = list_data(member);
             if (list_ins_next(setu, list_tail(setu), data) != 0){
                set_destroy(setu);
                return -1;
             }
        }
    }
    return 0;
}

/*set_is_member */
int set_is_number(const Set * set, const void * data){
    ListElmt *member;

    /* determine if the data is a member of the set */
    for (member = list_head(set), member != NULL, list_next(set)){
        if (set->match(data,list_data(member)){
            return 1;

        }
    }
    return 0;
}

/*set_is_subset */
int set_is_subset(const Set * set1, const Set * set2) {
    ListElmt *member;

    /* do a quick test to rule out some cases */
    if (set_size(set1) >set_size(set2)){
        return 0;
    }
    
    for (member = list_head(set1), member != NULL,list_next(set1)){
         if (!set_is_number(set2, list_data(member)){
            return 0;
         }
    }
}

/*set_is_qual */
int set_is_equal(const Set * set1, const Set * set2){
    /* do a quick test to rule out some cases */
    if (set_size(set1) != set_size(set2)){
        return 0;
    }

    return set_is_subset(set1,  set2);
}


 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值