The LevAWC Project
 All Data Structures Files Functions Variables Typedefs Enumerations Macros Pages
set.c
Go to the documentation of this file.
1 /*
2  * _____
3  * ANSI / ___/
4  * / /__
5  * \___/
6  *
7  * Filename: set.c
8  * Author : Kyle Loudon/Dan Levin
9  * Date : Mon Apr 08 12:32:13 2013
10  * Version : 0.51
11  * ---
12  * Description: A pure, generic set ADT - written in ANSI C
13  *
14  * Date Revision message
15  * 130413 Created this file
16  * 150331 This code ready for version 0.51
17  *
18  */
23 #include <stdio.h>
24 #include <stdlib.h>
25 
26 #include "set.h"
27 
28 
29 /* --- Function: Set SETinit(int (*match)(const void *key1, const void *key2), void (*destroy)(void *data)) --- */
30 Set SETinit(int (*match)(const void *key1, const void *key2), void (*destroy)(void *data))
31 {
32  Set set;
33 
34  set = SLISTinit(destroy);
35 
36  if (set)
37  SLISTsetmatch(set, match);
38 
39  return set;
40 }
41 
42 /* --- Furnction: void SETdestroy(Set set) --- */
43 void SETdestroy(Set set)
44 {
45  SLISTdestroy(set);
46 }
47 
48 /* --- Function: int SETinsert(Set set, const void *data) --- */
49 int SETinsert(Set set, const void *data)
50 {
51  /* Do not allow the insertion of duplicates */
52  if (SETis_member(set, data))
53  return 1;
54 
55  /* Insert the data */
56  return SLISTinsnext(set, SLISTtail(set), data);
57 }
58 
59 /* --- Function: int SETremove(Set set, void **data) --- */
60 int SETremove(Set set, void **data)
61 {
62  return SLISTfind_remove(set, data);
63 }
64 
65 /* --- Function: Set SETunion(Set set1, Set set2) --- */
66 Set SETunion(Set set1, Set set2)
67 {
68  Set setu;
69  SlistNode member;
70  void *data;
71 
72  /* Initialize the set for the union */
73  setu = SETinit(SLISTgetmatch(set1), NULL);
74 
75  /* Insert the members of the first set */
76  for (member = SLISThead(set1); member != NULL; member = SLISTnext(member))
77  {
78  data = SLISTdata(member);
79 
80  if (SLISTinsnext(setu, SLISTtail(setu), data) != 0)
81  {
82  SETdestroy(setu);
83  return NULL;
84  }
85 
86  }
87 
88  /* Insert the members of the second set */
89  for (member = SLISThead(set2); member != NULL; member = SLISTnext(member))
90  {
91  if (SETis_member(set1, SLISTdata(member)))
92  {
93  /* Do not allow the insertion of duplicates */
94  continue;
95  }
96  else
97  {
98  data = SLISTdata(member);
99 
100  if (SLISTinsnext(setu, SLISTtail(setu), data) != 0)
101  {
102  SETdestroy(setu);
103  return NULL;
104  }
105  }
106  }
107 
108  return setu;
109 }
110 
111 /* --- Function: Set SETintersection(Set set1, Set set2) --- */
113 {
114  Set seti;
115  SlistNode member;
116  void *data;
117 
118  /* Initialize the set for the intersection */
119  seti = SETinit(SLISTgetmatch(set1), NULL);
120 
121  /* Insert the members present in both sets */
122  for (member = SLISThead(set1); member != NULL; member = SLISTnext(member))
123  {
124  if (SETis_member(set2, SLISTdata(member)))
125  {
126  data = SLISTdata(member);
127 
128  if (SLISTinsnext(seti, SLISTtail(seti), data) != 0)
129  {
130  SETdestroy(seti);
131  return NULL;
132  }
133  }
134  }
135 
136  return seti;
137 }
138 
139 /* --- Function: Set SETdifference(Set set1, Set set2) --- */
141 {
142  Set setd;
143  SlistNode member;
144  void *data;
145 
146  /* Initialize the set for the difference */
147  setd = SETinit(SLISTgetmatch(set1), NULL);
148 
149  /* Insert the members from set1 not in set2 */
150  for (member = SLISThead(set1); member != NULL; member = SLISTnext(member))
151  {
152  if (!SETis_member(set2, SLISTdata(member)))
153  {
154  data = SLISTdata(member);
155 
156  if (SLISTinsnext(setd, SLISTtail(setd), data) != 0)
157  {
158  SETdestroy(setd);
159  return NULL;
160  }
161  }
162  }
163 
164  return setd;
165 }
166 
167 /* --- Function: int SETis_member(Set set, const void *data) --- */
168 int SETis_member(Set set, const void *data)
169 {
170  if (SLISTfindnode(set, data) != NULL)
171  return 1;
172  else
173  return 0;
174 }
175 
176 /* --- Function: int SETis_subset(const Set set1, const Set set2) --- */
177 int SETis_subset(const Set set1, const Set set2)
178 {
179  SlistNode tmp;
180 
181  /* Do a quick test to rule out some cases */
182  if (SETsize(set1) > SETsize(set2))
183  return 0;
184 
185  /* Determine if set1 is a subset of set2 */
186  for (tmp = SLISThead(set1); tmp != NULL; tmp = SLISTnext(tmp))
187  {
188  if (!SETis_member(set2, SLISTdata(tmp)))
189  return 0;
190  }
191 
192  return 1;
193 }
194 
195 /* --- Function: int SETis_equal(Set set1, Set set2) --- */
196 int SETis_equal(Set set1, Set set2)
197 {
198  /* Do a quick test to rule out some cases */
199  if (SETsize(set1) != SETsize(set2))
200  return 0;
201 
202  /* Sets of the same size are equal if they are subsets */
203  return SETis_subset(set1, set2);
204 }
205 
206 /* --- Function: int SETsize(Set set) --- */
207 int SETsize(Set set)
208 {
209  return SLISTsize(set);
210 }
211 
212 /* --- Function: void SETsort(Set set, int (*cmp)(const void *key1, const void *key2)) --- */
213 void SETsort(Set set, int (*cmp)(const void *key1, const void *key2))
214 {
215  SLISTsort(set, cmp);
216 }
217 
218 /* --- Function: void SETtraverse(Set set, void (*callback)(const void *data), int direction) --- */
219 void SETtraverse(Set set, void (*callback)(const void *data), int direction)
220 {
221  SLISTtraverse(set, callback, direction);
222 }