C.Interface.And.Implementations—set的实现

来源:互联网 发布:关联规则算法有哪些 编辑:程序博客网 时间:2024/04/28 17:27

1、A set is an  unordered collection of distinct members. 

2、The basic operations on a set are testing  for membership, adding members, and removing members. 

3、Other operations include set union, intersection, difference, and symmetric difference. 


set实现类似于table(key-value系统)的实现,采用类似的“哈希表和链表”的底层数据结构。可以参看上一章的内容。


=============================set.h==============================

#ifndef SET_INCLUDED#define SET_INCLUDED#define T Set_Ttypedef struct T *T;//exported functionsextern T      Set_new   (int hint,    int cmp(const void *x, const void *y),    unsigned hash(const void *x));extern void   Set_free  (T *set);extern int    Set_length(T set);extern int    Set_member(T set, const void *member);extern void   Set_put   (T set, const void *member);extern void  *Set_remove(T set, const void *member);extern void   Set_map   (T set,    void apply(const void *member, void *cl), void *cl);extern void **Set_toArray(T set, void *end);extern T      Set_union (T s, T t);extern T      Set_inter (T s, T t);extern T      Set_minus (T s, T t);extern T      Set_diff  (T s, T t);#undef#endif

=============================set.c============================

#include <limits.h>#include <stddef.h>#include "mem.h"#include "assert.h"#include "arith.h"#include "set.h"#define T Set_T//typesstruct T{    int length;    unsigned timestamp;    int (*cmp)(const void *x, const void *y);    unsigned (*hash)(const void *x);    int size;    struct member{        struct member *link;        const void *member;    } **buckets;}//static functionsstatic int cmpatom(const void *x, const void *y){    return x != y;}static unsigned hashatom(const void *x){    return (unsigned long)x>>2;}static T copy(T t, int hint){    T set;    assert(t);    set = Set_new(hint, t->cmp, t->hash);    {        int i;        struct member *q;        for(i = 0; i < t->size; ++i){            for(q = t->buckets[i]; q; q = q->link){                struct member *p;                const void *member = q->member;                int i = (*set->hash)(member)%set->size;                NEW(p);                p->member = member;                p->link = set->buckets[i];                set->buckets[i] = p;                set->length++;            }        }    }    return set;}//functionsT Set_new(int hint,    int cmp(const void *x, const void *y),    unsigned hash(const void *x)){    T set;    int i;    static int primes[] = { 509, 509, 1021, 2053, 4093,        8191, 16381, 32771, 65521, INT_MAX };        assert(hint >= 0);    for(i = 1; primes[i] < hint; ++i){        ;    set = ALLOC(sizeof(*set) +        primes[i-1]*sizeof(set->buckets[0]));    set->size = primes[i-1];    set->cmp = cmp ? cmp : cmpatom;    set->hash = hash ? hash : hashatom;    set->buckets = (struct member **)(set + 1);    for(i = 0; i < set->size; ++i){        set->buckets[i] = NULL;    }    set->length = 0;    set->timestamp = 0;        return set;}int Set_member(T set, const void *member){    int i;    struct member *p;    assert(set);    assert(member);    //search set for member    i = (*set->hash)(member)%set->size;    for(p = set->buckets[i]; p; p = p->link){        if((*set->cmp)(member, p->member) == 0)            break;    }    return p != NULL;}void Set_put(T set, const void *member){    int i;    struct member *p;    assert(set);    assert(member);    //search set for member    i = (*set->hash)(member)%set->size;    for(p = set->buckets[i]; p; p = p->link){        if((*set->cmp)(member, p->member) == 0)            break;    }    if(p == NULL){        //add member to set        NEW(p);        p->member = member;        p->link = set->buckets[i];        set->buckets[i] = p;        set->length++;    }else{        p->member = member;    }    set->timestamp++;}void *Set_remove(T set, const void *member){    int i;    struct member **pp;    assert(set);    assert(member);    set->timestamp++;    i = (*set->hash)(member)%set->size;    for(pp = &set->buckets[i]; *pp; pp = &(*pp)->link){        if((*set->cmp)(member, (*pp)->member) == 0){            struct member *p = *pp;            *pp = p->link;            member = p->member;            FREE(p);            set->length--;            retunr (void *)member;        }    }    return NULL;}int Set_length(T set){    assert(set);    return set->length;}void Set_free(T *set){    assert(set && *set);    if((*set)->length > 0){        int i;        struct member *p; *q;        for(i = 0; i < (*set)->size; ++i){            for(p = (*set)->buckets[i]; p; p = q){                q = p->link;                FREE(p);            }        }    }    FREE(*set);}void Set_map(T set,    void apply(const void *member,  void *cl), void *cl){    int i;    unsigned stamp;    struct member *p;    assert(set);    assert(apply);    stamp = set->timestamp;    for(i = 0; i < set->size; ++i){        for(p = set->buckets[i]; p; p = p->link){            apply(p->member, cl);            assert(set->timestamp == stamp);        }    }}void **Set_toArray(T set, void *end){    int i, j = 0;    void **array;    struct member *p;    assert(set);    array = ALLOC((set->length + 1)*sizeof(*array));    for(i = 0; i < set->size; ++i){        for(p = set->buckets[i]; p; p = p->link){            array[j++] = (void *)p->member;        }    }    array[j] = end;        return array; }T Set_union(T s, T t){    if(s == NULL){        assert(t);        return copy(t, t->size);    }else if( t == NULL){        return copy(s, s->size);    }else{        T set = copy(s, Arith_max(s->size, t->size));        assert(s->cmp == t->cmp && s->hash == t->hash);        {            //for each member q in t            int i;            struct member *q;            for(i = 0; i < t->size; ++i){                for(q = t->buckets[i]; q; q = q->link){                    Set_put(set, q->member);                }            }        }        return set;    }}T Set_inter(T s, T t){    if(s == NULL){        assert(t);        return Set_new(t->size, t->cmp, t->hash);    }else if( t == NULL){        return Set_new(s->size, s->cmp, s->hash);    }else if(s->length < t->length){        return Set_inter(t, s);    }else{        T set = Set_new(Arith_min(s->size, t->size),             s->cmp, s->hash);        assert(s->cmp == t->cmp && s->hash == t->hash);        {            int i;            struct member *q;            for(i = 0; i < t->size; ++i){                for(q = t->buckets[i]; q; q = q->link){                    if(Set_member(s, q->member)){                        struct member *p                        const void *member = q->member;                        int i = (*set->hash)(member)%set->size;                        NEW(p);                        p->member = member;                        p->link = set->buckets[i];                        set->buckets[i] = p;                        set->length++;                    }                }            }        }        return set;    }}T Set_minus(T t, T s){    if(t == NULL){        assert(s);        return Set_new(s->size, s->cmp, s->hash);    }else if(s == NULL){        return copy(t, t->size);    }else{        T set = Set_new(Arith_min(s->size, t->size),            s->cmp, s->hash);        assert(s->cmp == t->cmp && s->hash == t->hash);        {            int i;            struct member *q;            for(i = 0; i < t->size; ++i){                for(q = t->buckets[i]; q; q = q->link){                    if(!Set_member(s, q->member)){                        struct member *p;                        const void *member = q->member;                        int i = (*set->hash)(member)%set->size;                        NEW(p);                        p->member = member;                        p->link = set->buckets[i];                        set->buckets[i] = p;                        set->length++;                    }                }            }        }        return set;    }}T Set_diff(T s, T t){    if(s == NULL){        assert(t);        return copy(t, t->size);    }else if(t == NULL){        return copy(s, s->size);    }else{        T set = Set_new(Arith_min(s->size, t->size),            s->cmp, s->hash);        assert(s->cmp == t->cmp && s->hash == t->hash);        {            int i;            struct member *q;            for(i = 0; i < t->size; ++i){                for(q = t->buckets[i]; q; q = q->link){                    if(!Set_member(s, q->member)){                        struct member *p;                        const void *member = q->member;                        int i = (*set->hash)(member)%set->size;                        NEW(p);                        p->member = member;                        p->link = set->buckets[i];                        set->buckets[i] = p;                        set->length++;                    }                }            }        }        {T u = t; t = s; s = u;}        {            int i;            struct member *q;            for(i = 0; i < t->size; ++i){                for(q = t->buckets[i]; q; q = q->link){                    if(!Set_member(s, q->member)){                        struct member *p;                        const void *member = q->member;                        int i = (*set->hash)(member)%set->size;                        NEW(p);                        p->member = member;                        p->link = set->buckets[i];                        set->buckets[i] = p;                        set->length++;                    }                }            }        }        return set;    }}


0 0
原创粉丝点击