//
// Set.h
// Algorithms&Data_structures
//
// Created by TTc on 15-2-2.
// Copyright (c) 2015年 TTc. All rights reserved.
//
#ifndef __Algorithms_Data_structures__Set__
#define __Algorithms_Data_structures__Set__
#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));
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_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_destroy list_destroy
#define set_size(set) ((set)->size)
#endif /* defined(__Algorithms_Data_structures__Set__) */
//
// Set.c
// Algorithms&Data_structures
//
// Created by TTc on 15-2-2.
// Copyright (c) 2015年 TTc. All rights reserved.
//
#include "Set.h"
#include <stdlib.h>
void
set_init(Set *set,int (*match)(const void *key1,const void * key2),
void (*destroy)(void *data)){
list_init(set, destroy);
set->match = match;
}
/*
将一个成员插入到集合中,由于集合中的成员只能出现一次,因此将首先调用set_is_member以确保集合中不会已经包含了待插入的成员;若集合中不存在待插入的成员,就调用list_ins_next将待插入的成员插入到集合中
*/
/* set_inert的复杂度为O(n)级,因为set_is_member需要遍历整个集合,需要O(n) ;而list_ins_next则以O(1)插入*/
int
set_insert(Set *set, const void * data){
if(set_is_number(set, data)){
return 1;
}
return list_ins_next(set, list_tail(set), data);
}
/*
set_remove 复杂度为O(n) ,n为集合的成员size
*/
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;
}
if(member == NULL)
return -1;
return list_rem_next(set, prev, data);
}
/*
set_union
1:操作将建立一个集合,记做setu,由参数set1与set2所指定的集合的并集结果;
2:复杂度为O(mn) ,m,n分别为集合set1与set2的成员个数
3:在第一个循环中,遍历了set1中的每个成员并且把他们插入setu中,这个过程的时间复杂度O(m)
5:在第二个循环中,遍历了set2中的每个成员并且把他们插入setu中,这个过程的时间复杂度O(n)
而这个循环需要包含时间复杂度为O(n)的set_is_member,因此第二次循环的总体复杂度为O(mn)
6:由于这两个循环是顺序执行的,因此set_union的运行时复杂度比单独执行这两次循环还要大,
记为O(mn)
*/
int
set_union(Set *setu,const Set *set1,const Set *set2){
ListElmt *member;
void *data;
set_init(setu, set1->match, NULL);
// insert the members of the first set
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;
}
}
// insert the members of the second set
for (member = list_head(set2); member != NULL; member = list_next(member)) {
if(set_is_number(set1, list_data(member))){
continue;
} else{
data = list_data(member);
if(list_ins_next(setu, list_tail(setu), data)){
set_destroy(setu);
return -1;
}
}
}
return 0;
}
/*
set_intersection
1:操作将建立一个集合,记做seti,由参数set1与set2所指定的集合的交集结果;
2:复杂度为O(mn) ,m,n分别为集合set1与set2的成员个数
*/
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; member = list_next(member)) {
if(set_is_number(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
1:操作将建立一个集合,记做setd,由参数set1与set2所指定的集合的差集结果;
2:复杂度为O(mn) ,m,n分别为集合set1与set2的成员个数
*/
int
set_difference(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; member = list_next(member)) {
if(!set_is_number(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用来判断某个成员是否再集合中出现过 复杂度为O(n) ,n为集合的成员size
*/
int
set_is_number(const Set *set,const void *data){
ListElmt *member ;
//O(n)
for (member = list_head(set); member != NULL; member = list_next(member)) {
if(set->match(data,list_data(member))){
return 1;
}
}
return 0;
}
/*
set_is_subset 操作用来判断集合set1是否为集合set2的子集合
1:由于一个集合是另外一个集合的子集,则set1所包含的成员个数必须要小于等于set2所包含的
成员个数,因此首先比较它们的成员个数
复杂度为O(mn),m,n分别为set1与set2的成员个数size
*/
int
set_is_subset(const Set *set1,const Set *set2){
ListElmt *member;
if(set_size(set1) > set_size(set2)){
return 0;
}
for (member = list_head(set1); member != NULL; member = list_next(member)) {
if(!set_is_number(set2,list_data(member)))
return 0;
}
return 1;
}
/*
set_is_equal用来判断set1与set2是否相等
1:因为两个相等的集合必然有相同的成员个数size,所以就从比较它们的成员个数size开始
2:若两个集合的成员个数不等,则两个集合必然不想等
3:如果两个集合的成员个数相同,只需要确定set1是否为set2的子集就可以返回结果了,
可以通过调用set_is_subset来实现
4:set_is_subset 运行时 复杂度为O(mn),m,n分别为set1与set2的成员个数size
*/
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);
}