前面已经介绍了链表、栈和队列的实现,也了解到在栈和队列的实现过程中,都用到的单链表的函数接口。下面介绍新的:集合。
集合是不同对象的无序的聚集,集合的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);
}