A linked list is an ideal way to implement a collection . Renames the list to set as a typedef. This preserves the concise nature of the list and enables the collection to have some polymorphic properties.
The biggest benefit of using this approach is that you can use List_next to traverse a collection and use List_rem_next to remove a member without identifying it based on the data stored by the member.
Let's start by looking at the contents of the collection abstract data type header file:
Example 1: Collection (abstract data type) header file
#ifndef Set_h#defineSet_h#include<stdlib.h>#include"list.h"/ * Defines the collection as a list structure */typedef list set;/* Initialization of the collection * /voidSet_init (Set *Set,int(match*) (Const void*key1,Const void*key2),void(*destroy) (void*data)); * Set destruction, defined as linked list destruction function */#defineSet_destroy list_destroy/* inserting elements into the collection */intSet_insert (Set *Set,Const void**/* Remove elements from the collection * /intSet_remove (Set *Set,void**data);/* Find the set of aggregates * /intSet_union (Set *setu,ConstSet *set1,ConstSet *Set2);/* Find the intersection of sets * /intSet_intersection (Set *seti,ConstSet *set1,ConstSet *Set2);/* Find the difference set of the set * /intSet_difference (Set *setd,ConstSet *set1,ConstSet *Set2);/* Determines whether a member belongs to a collection * /intSet_is_member (ConstSet *Set,Const void*data); / * Subset of Judgment * /intSet_is_subset (ConstSet *set1,ConstSet *Set2);/* Determines whether the collection is equal * /intSet_is_equal (ConstSet *set1,ConstSet *Set2);/* The number of elements in the collection * /#defineSet_size (set) (set)->size)#endif
Here are the specific implementations of the various operations:
Example 2: Implementation of a collection abstract data type
#include <stdlib.h>#include<string.h>#include"list.h"#include"set.h"/*Set_init Initialization of a collection*/voidSet_init (Set *Set,int(*match) (Const void*key1,Const void*key2),void(*destroy) (void*data)) { /*Call List_init*/List_init (Set, destroy); /*initialize the match member separately*/ Set->match =match; return;}/*Set_insert inserting a member into the collection*/intSet_insert (Set *Set,Const void*Data) {/* Cannot insert an existing member into the collection */
if (Set_is_member (Set,data))
return-1;
/* Call List_ins_next Insert element to end */
Return List_ins_next (Set,list_tail (set), data);
}
/*set_remove removing elements */
int Set_remove (set *set,void **data)
{
LISTELMT *member, *prev;
/* Find the member you want to remove */
Prev=null;
/* Traverse linked list */
For (Member=list_head (set); member! = NULL; member = List_next (member))
{
if (Set->match (*data, (List_data (member)))
Break
Prev=member; /*prev just points to the previous member of the matching successful member */
}
/* Return if no member is found */
if (member==null)
return-1;
/* Remove Members */
Return List_rem_next (Set,prev,data);
}
/*set_union solving a set of two sets */
int Set_union (set *setu,const set *set1,const set *set2)
{
LISTELMT *member;
void *data;
/* Initialize a set of aggregates */
Set_init (Setu,set1->match,null);
/* Insert the contents of collection 1 into the 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 member of Collection 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 solving the intersection of two sets */
int Set_intersection (set *seti,const set *set1,const set *set2)
{
LISTELMT *member;
void *data;
/* Initialize intersection set */
Set_init (Seti,set1->match,null);
/* elements that occur at the same time in two sets are inserted in the set of intersections */
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 solving the difference set of two sets */
int Set_intersection (set *setd,const set *set1,const set *set2)
{
LISTELMT *member;
void *data;
/* Initialize set of differences */
Set_init (Setd,set1->match,null);
/* elements that are not present in two sets will be inserted in the set of differences */
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 determines whether the member specified by data is in the collection specified by 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 determines whether the set SET1 is a subset of the collection Set2 */
int Set_is_subset (const set *SET1,CONST set *set2)
{
LISTELMT *member;
/* First exclude the number of sets 1 members greater than the number of members of the set 2 */
if (Set_size (Set1) >set_size (Set2))
return 0;
/* If the SET1 members are not in the Set2, then the judgment is not established, except for this establishment * *
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 to determine whether two sets are equal/*
int set_is_equal (const set *SET1,CONST set *set2)
{
/* First exclude two sets of members with unequal number of cases */
if (Set_size (set1)! = Set_size (Set2))
return 0;
/* When the number of two collection members is equal, and one collection is a subset of the other, the two collections are equal */
Return Set_is_subset (Set1,set2);
}
The C language implementation of data structure collection (mathematics) abstract type