-
Notifications
You must be signed in to change notification settings - Fork 9
/
set.c
252 lines (227 loc) · 4.87 KB
/
set.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
/**
* @filename: set.c
*
* @author: QinYUN575
*
* @create date: 2019/11/3
*
*
*
*/
#include <stdlib.h>
#include "list.h"
#include "set.h"
/**
* 初始化集合
*
* @param Set *set 指定需要初始化的集合
*
* @param int (*match)(const void *key1, const void *key2) 指定匹配判断函数
*
* @param void (*destroy)(void *data) 指定用于销毁集合的操作
*
*/
void set_init(Set *set, int (*match)(const void *key1, const void *key2),
void (*destroy)(void *data))
{
list_init(set, destroy);
set->match = match;
return;
}
/**
* 将一个成员插入集合中
*
* @param Set *set 指定要插入的集合
*
* @param const void *data 插入元素数据
*
*/
int set_insert(Set *set, const void *data)
{
if (set_is_member(set, data))
{
return 1;
}
return list_ins_next(set, list_tail(set), data);
}
/**
* 将一个成员从集合中移除
*
* @param Set *set 指定要操作的集合
*
* @param const void *data 指定要移除的元素数据
*
*/
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, member->data))
{
break;
}
prev = member;
}
if (member == NULL)
{
return -1;
}
return list_rem_next(set, prev, data);
}
/**
* 求 set1 与 set2 的并集
*
* @param Set *setu set1 set2 的并集
*
* @param Set *set set1
*
* @param Set *set set2
*
*/
int set_union(Set *setu, const Set *set1, const Set *set2)
{
ListElmt *member;
void *data;
set_init(setu, setu->match, NULL);
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;
}
}
for (member = list_head(set2); member != NULL; member = list_next(member))
{
if (!set_is_member(set1, member->data))
{
data = list_data(member);
if (list_ins_next(setu, list_tail(setu), data) != 0)
{
set_destroy(setu);
return -1;
}
}
}
return 0;
}
/**
* 求 set1 与 set2 的交集
*
* @param Set *seti set1 与 set2 交集
*
* @param Set *set set1
*
* @param Set *set set2
*
*/
int set_intersection(Set *seti, const Set *set1, const Set *set2)
{
ListElmt *member;
void *data;
set_init(seti, seti->match, NULL);
for (member = list_head(set2); member != NULL; list_next(member))
{
data = list_data(member);
if (set_is_member(set1, data))
{
if (list_ins_next(seti, list_tail(seti), data))
{
set_destroy(seti);
return -1;
}
}
}
}
/**
* 求 set1 与 set2 的差集
*
* @param Set *setd set1 与 set2 差集
*
* @param Set *set set1
*
* @param Set *set set2
*
*/
int set_difference(Set *setd, const Set *set1, const Set *set2)
{
ListElmt *member;
void *data;
set_init(setd, setd->match, NULL);
for (member = list_head(set2); member != NULL; member = list_next(member))
{
data = list_data(member);
if (!set_is_member(set1, data))
{
if (list_ins_next(setd, list_tail(setd), data))
{
set_destroy(setd);
return -1;
}
}
}
return 0;
}
/**
* 判断元素是否属于集合 set
*
* @param Set *setd 集合
*
* @param const void *data 需要匹配的元素数据
*
*/
int set_is_member(const Set *set, const void *data)
{
ListElmt *member;
for (member = list_head(set); member != NULL; member = list_next(member))
{
if (set->match(data, list_data(member)))
{
return 1;
}
}
return 0;
}
/**
* 判断 set1 是否为 set2 的子集
*
* @param Set *set1
*
* @param Set *set2
*
*/
int set_is_subset(const Set *set1, const Set *set2)
{
ListElmt *member;
if (set_size(set1) > set_size(set2))
{
return 0;
}
for (member = list_head(set1); member != NULL; list_next(member))
{
if (!set_is_member(set2, list_data(member)))
{
return 0;
}
}
return 1;
}
/**
* 判断两个集合是否相等
*
* @param Set *set1
*
* @param Set *set2
*
*/
int set_is_equal(const Set *set1, const Set *set2)
{
if (set_size(set1) != set_size(set2))
{
return 0;
}
return set_is_subset(set2, set1);
}