Skip to content

Commit fc71a94

Browse files
committed
added union function
1 parent 83f2859 commit fc71a94

File tree

2 files changed

+84
-1
lines changed

2 files changed

+84
-1
lines changed

include/list.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <stdbool.h>
77
#include <string.h>
88
#include <pthread.h>
9+
#include <assert.h>
910

1011
typedef struct ListNode_s {
1112
void *data;
@@ -18,8 +19,10 @@ typedef struct List_s {
1819
void (*del) (void *);
1920
pthread_mutex_t lock;
2021
char *(*toString) (void *);
21-
int (*compare)(void *, void *);
22+
int (*compare)(const void *, const void *);
2223
void (*print) (void *);
24+
void *(*copy) (void *);
25+
size_t elem_size;
2326
const char *name;
2427
} List_t;
2528

@@ -29,6 +32,7 @@ List_t *list_initWithN(size_t n, ...);
2932
void list_destroy(List_t *l);
3033

3134
void list_setPrintFunc(List_t *l, void (*print) (void *));
35+
void list_setCompFunc(List_t *l, int (*compare) (const void *, const void *));
3236

3337
void *list_findByInt(List_t *l, int (*toInt) (void *), int i);
3438
void *list_findByString(List_t *l, void (*toString) (char *,void *), const char *str);
@@ -52,9 +56,15 @@ void list_filterDelete(List_t *l, bool (*pred) (void *));
5256
void list_map(List_t *l, void *(*f) (void *));
5357
/* same as above, but frees original. */
5458
void list_mapDelete(List_t *l, void *(*f) (void *));
59+
/* sorts based on provided compare function */
60+
void list_sort(List_t *l);
61+
/* performs a union of two lists using compare function */
62+
List_t list_union(List_t *l1, List_t *l2);
5563

5664
ListNode_t *listNode_init(void *data, ListNode_t *next, ListNode_t *prev);
5765

66+
List_t list_deepCopy(List_t *l);
67+
5868
/* Threadsafe */
5969
bool list_addBack(List_t *l, void *data);
6070
void *list_removeBack(List_t *l);

src/list.c

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,3 +334,76 @@ void list_mapDelete(List_t *l, void *(*f) (void *)) {
334334
node = node->next;
335335
}
336336
}
337+
338+
void list_sort(List_t *l) {
339+
if (!l->compare) {
340+
fprintf(stderr, "Error: no compare function defined. Cannot sort.\n");
341+
return;
342+
}
343+
if (!l->elem_size) {
344+
fprintf(stderr, "Error: element size is not defined. Cannot sort.\n");
345+
return;
346+
}
347+
if (l->size > 0) {
348+
/* copy all elements into an array */
349+
void **arr = calloc(l->size, sizeof(void *));
350+
ListNode_t *node = l->front;
351+
size_t idx = 0;
352+
while (node) {
353+
ListNode_t *next = node->next;
354+
arr[idx++] = node->data;
355+
list_removeNode(l, node); /* frees the node, not the data*/
356+
node = next;
357+
}
358+
359+
assert(l->size == 0 && "List is not empty for some reason");
360+
/* use quicksort to sort the array */
361+
qsort(arr, l->size, l->elem_size, l->compare);
362+
363+
/* copy the elements back */
364+
for (idx = 0; idx < l->size; ++idx) {
365+
list_addBack(l, arr[idx]);
366+
}
367+
}
368+
}
369+
370+
List_t list_union(List_t *l1, List_t *l2) {
371+
if (!l1->copy || !l2->copy) {
372+
fprintf(stderr, "Error: copy function not defined. Can't perform union\n");
373+
exit(1);
374+
}
375+
if (!l1->compare || (l1->compare != l2->compare)) {
376+
fprintf(stderr, "Error: compare not defined, or not the same comparison"
377+
"function. Can't perform union\n");
378+
exit(1);
379+
} else if (l1->size == 0) {
380+
return list_deepCopy(l2);
381+
} else if (l2->size == 0) {
382+
return list_deepCopy(l1);
383+
} else {
384+
List_t res;
385+
list_init(&res, l1->del ? l1->del : l2->del);
386+
}
387+
}
388+
389+
List_t list_deepCopy(List_t *l) {
390+
if (!l->copy) {
391+
fprintf(stderr, "Error: no copy function defined. Can't deepCopy\n");
392+
exit(1);
393+
} else {
394+
List_t res;
395+
ListNode_t *node = l->front;
396+
list_init(&res, l->del);
397+
res.copy = l->copy;
398+
res.toString = l->toString;
399+
res.print = l->print;
400+
res.elem_size = l->elem_size;
401+
res.name = l->name;
402+
while (node) {
403+
list_addBack(&res, l->copy(node->data));
404+
node = node->next;
405+
}
406+
assert(res.size == l->size && "Sizes don't match for some reason");
407+
return res;
408+
}
409+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy