標籤:ring turn next 沒有 初始化 操作 des nio lib
鏈表是實現集合的一種理想的方式。將List以typedef的方式重新命名為Set。這樣做能保留鏈表簡潔的特性,還能使集合具有了一些多態的特性。
使用這種方法的最大好處就是可以使用list_next來遍曆一個集合,使用list_rem_next來移除一個成員,而不用根據成員所儲存的資料來標識它。
我們先來查看一下集合抽象資料類型標頭檔的內容:
樣本1:集合(抽象資料類型)標頭檔
#ifndef SET_H#define SET_H #include <stdlib.h>#include "list.h"/*將集合定義成List結構*/typedef List Set;/*集合的初始化*/void set_init(Set *set,int (match*)(const void *key1,const void *key2),void(*destroy)(void *data));/*集合銷毀,定義成鏈表銷毀函數*/#define set_destroy List_destroy/*向集合中插入元素*/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_member(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
下面是各種操作的具體實現:
樣本2:集合抽象資料類型的實現
#include <stdlib.h>#include <string.h>#include "list.h"#include "set.h"/*set_init 初始化一個集合*/void set_init(Set *set,int(*match)(const void *key1,const void *key2), void(*destroy)(void *data)){ /*調用list_init*/ list_init(set,destroy); /*單獨初始化match成員*/ set->match = match; return;}/*set_insert 向集合中插入一個成員*/int set_insert(Set *set,const void *data){ /*不能向集合中插入已有成員*/
if(set_is_member(set,data))
return -1;
/*調用list_ins_next插入元素至尾端*/
return list_ins_next(set,list_tail(set),data);
}
/*set_remove 移除元素*/
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; /*prev剛好指向匹配成功的成員的前一個成員*/
}
/*沒有找到成員則返回*/
if(member==NULL)
return -1;
/*移除成員*/
return list_rem_next(set,prev,data);
}
/*set_union 求解兩個集合的並集*/
int set_union(Set *setu,const Set *set1,const Set *set2)
{
ListElmt *member;
void *data;
/*初始化一個並集集合*/
set_init(setu,set1->match,NULL);
/*將集合1的內容插入並集*/
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;
}
}
/*插入集合2的成員*/
for(member=list_head(set2);member!=NULL;member=list_next(member))
{
if(set_is_member(set1,list_data(member)))
{
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;
/*初始化交集集合*/
set_init(seti,set1->match,NULL);
/*同時在兩個集合中出現的元素將被插入交集集合中*/
for(member=list_head(set1);member!=NULL;list_next(member))
{
if(set_is_member(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 求解兩個集合的差集*/
int set_intersection(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;list_next(member))
{
if( ! set_is_member(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 判斷由data指定的成員是否在由set指定的集合中*/
int set_is_member(const Set *set,void *data)
{
ListElmt *member;
for(member=list_head(set);member!=NULL;list_next(member))
{
if(set->match(data,list_data(member))
return 1;
}
return 0;
}
/*set_is_subset 判斷集合set1是否是集合set2的子集*/
int set_is_subset(const Set *set1,const Set *set2)
{
ListElmt *member;
/*首先排除集合1成員數量大於集合2成員數量的情況*/
if(set_size(set1)>set_size(set2))
return 0;
/*如果set1的成員不都在set2中,則判斷不成立,除此成立*/
for(member=list_head(set1);member!=NULL;list_next(member))
{
if( !set_is_member(set2,list_data(member)))
{
return 0;
}
}
return 1;
}
/*set_is_equal 判斷兩個集合是否相等*/
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);
}
資料結構 集合_集合(數學)抽象資料類型的C語言實現