資料結構 集合_集合(數學)抽象資料類型的C語言實現

來源:互聯網
上載者:User

標籤: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語言實現

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.