集合:由一个或多个确定的元素所构成的整体,集合中没有重复的数据
头文件:
#ifndef set_h
#define set_h
#include <stdio.h>
#define set_size(set) ((set)->size);
typedef struct SetElemenet_{
void *data;
struct SetElemenet_* pre;
struct SetElemenet_*next;
}SetElement,*SetElementP;
typedef struct Set_{
int size;
void (*destroy)(void *data);
int (*match)(void *key1,void *key2);
SetElementP head;
}Set,*SetP;
void set_init(SetP set,void (*destroy)(void *data),int (*match)(void *key1,void* key2));
int set_insert(SetP set,void *data);
int set_insert_match(SetP set,void *data,int is_match);
int set_remove(SetP set,void *data);
int set_union(SetP setu,SetP set1,SetP set2);
int set_intersection(SetP seti,SetP set1,SetP set2);
int set_difference(SetP setd,SetP set1,SetP set2);
int set_is_member(SetP set,void *data);
int set_is_subset(SetP set1,SetP set2);
int set_is_equal(SetP set1,SetP set2);
void set_destroy(SetP set);
#endif /* set_h */
源文件:
#include "set.h"
#include <stdlib.h>
#include <string.h>
void set_init(SetP set,void (*destroy)(void *data),int (*match)(void *key1,void* key2)){
set->destroy=destroy;
set->head=NULL;
set->match=match;
set->size=0;
}
int set_insert_match(SetP set,void *data,int is_match){
int size=set_size(set);
if(is_match==1&&size>0&&set_is_member(set, data))
return 0;
SetElementP ele=malloc(sizeof(SetElement));
if(!ele)
return 0;
ele->data=data;
set->size++;
if(size==0){
set->head=ele;
ele->next=NULL;
ele->pre=NULL;
}else{
ele->next=set->head;
set->head->pre=ele;
set->head=ele;
}
return 1;
}
int set_insert(SetP set,void *data){
return set_insert_match(set,data,1);
}
int set_remove(SetP set,void *data){
SetElementP p=set->head;
while (p) {
if(set->match(data,p->data)==0){
p->pre->next=p->next;
p->next->pre=p->pre;
set->size--;
free(p);
return 1;
}
p=p->next;
}
return 0;
}
int set_union(SetP setu,SetP set1,SetP set2){
int size1=set_size(set1);
int size2=set_size(set2);
if(size1==0&&size2==0)
return 0;
set_init(setu, set1->destroy, set1->match);
if(size1==0){
SetElementP p=set2->head;
while (p) {
set_insert_match(setu, p->data, 0);
p=p->next;
}
return 1;
}else{
SetElementP p=set1->head;
while (p) {
set_insert_match(setu, p->data, 0);
p=p->next;
}
if(size2==0)
return 1;
p=set2->head;
while (p) {
set_insert_match(setu, p->data, 1);
p=p->next;
}
}
return 1;
}
int set_intersection(SetP seti,SetP set1,SetP set2){
set_init(seti, set1->destroy, set1->match);
SetElementP p=set1->head;
while (p) {
if(set_is_member(set2, p->data)){
set_insert_match(seti, p->data, 0);
}
p=p->next;
}
return seti->size>0?1:0;
}
int set_difference(SetP setd,SetP set1,SetP set2){
set_init(setd, set1->destroy, set1->match);
SetElementP p=set1->head;
while (p) {
if(!set_is_member(set2, p->data))
set_insert_match(setd, p->data, 0);
p=p->next;
}
return setd->size>0?1:0;
}
int set_is_member(SetP set,void *data){
if(set->match==NULL)
return 0;
SetElementP p=set->head;
while (p) {
if(set->match(p->data,data))
return 1;
p=p->next;
}
return 0;
}
int set_is_subset(SetP set1,SetP set2){
int size1=set_size(set1);
int size2=set_size(set2);
if(size2>size1)
return 0;
if(size1==0||size2==0)
return 1;
SetElementP p=set2->head;
while (p) {
if(!set_is_member(set1, p->data))
return 0;
}
return 1;
}
int set_is_equal(SetP set1,SetP set2){
int size1=set_size(set1);
int size2=set_size(set2);
return size1==size2&&set_is_subset(set1, set2)?1:0;
}
void set_destroy(SetP set){
SetElementP p=set->head;
while (p) {
SetElementP next=p->next;
set->destroy(p->data);
free(p);
p=next;
}
memset(set, 0, sizeof(Set));
}