This commit is contained in:
Evan Burkey 2021-02-01 14:27:01 -08:00
parent 86be1e8de5
commit d564364686
10 changed files with 106 additions and 106 deletions

View File

@ -1,3 +1,3 @@
# flint # libflint
My personal library of common C data structures and algorithms. My personal library of common C data structures and algorithms.

View File

@ -1,29 +1,29 @@
#ifndef LIBFLINT_BINARY_TREE_H #ifndef LIBFLINT_BINARY_TREE_H
#define LIBFLINT_BINARY_TREE_H #define LIBFLINT_BINARY_TREE_H
struct BinTreeNode { typedef struct BinTreeNode {
void *data; void *data;
struct BinTreeNode *left; struct BinTreeNode *left;
struct BinTreeNode *right; struct BinTreeNode *right;
}; } BinTreeNode;
struct BinTree { typedef struct {
int size; int size;
int (*compare)(const void *a, const void *b); int (*compare)(const void *a, const void *b);
void (*destroy)(void *data); void (*destroy)(void *data);
struct BinTreeNode *root; struct BinTreeNode *root;
}; } BinTree;
void bintree_init(struct BinTree *tree, void (*destroy)(void *data)); void bintree_init(BinTree *tree, void (*destroy)(void *data));
void bintree_destroy(struct BinTree *tree); void bintree_destroy(BinTree *tree);
int bintree_ins_left(struct BinTree *tree, struct BinTreeNode *node, void *data); int bintree_ins_left(BinTree *tree, BinTreeNode *node, void *data);
int bintree_ins_right(struct BinTree *tree, struct BinTreeNode *node, void *data); int bintree_ins_right(BinTree *tree, BinTreeNode *node, void *data);
void bintree_rem_left(struct BinTree *tree, struct BinTreeNode *node); void bintree_rem_left(BinTree *tree, BinTreeNode *node);
void bintree_rem_right(struct BinTree *tree, struct BinTreeNode *node); void bintree_rem_right(BinTree *tree, BinTreeNode *node);
int bintree_merge(struct BinTree *merge, struct BinTree *left, struct BinTree *right, void *data); int bintree_merge(BinTree *merge, BinTree *left, BinTree *right, void *data);
void bintree_debug_print(struct BinTree *tree); void bintree_debug_print(BinTree *tree);
#define bintree_is_eob(node) ((node) == NULL) #define bintree_is_eob(node) ((node) == NULL)
#define bintree_is_leaf(node) ((node)->left == NULL && (node)->right == NULL) #define bintree_is_leaf(node) ((node)->left == NULL && (node)->right == NULL)

View File

@ -3,13 +3,13 @@
#include <stddef.h> #include <stddef.h>
struct ListNode { typedef struct ListNode {
void* data; void* data;
struct ListNode* next; struct ListNode* next;
struct ListNode* prev; struct ListNode* prev;
}; } ListNode;
struct List { typedef struct {
size_t size; size_t size;
void (*destroy)(void* data); void (*destroy)(void* data);
@ -17,14 +17,14 @@ struct List {
struct ListNode* head; struct ListNode* head;
struct ListNode* tail; struct ListNode* tail;
}; } List;
void ll_init(struct List* list, void (*destroy)(void *data)); void ll_init(List* list, void (*destroy)(void *data));
void ll_destroy(struct List* list); void ll_destroy(List* list);
int ll_ins_next(struct List* list, struct ListNode* node, const void* data); int ll_ins_next(List* list, ListNode* node, const void* data);
int ll_ins_prev(struct List* list, struct ListNode* node, const void* data); int ll_ins_prev(List* list, ListNode* node, const void* data);
int ll_remove(struct List* list, struct ListNode* node, void** data); int ll_remove(List* list, ListNode* node, void** data);
int ll_remove_next(struct List* list, struct ListNode* node, void** data); int ll_remove_next(List* list, ListNode* node, void** data);
int ll_remove_prev(struct List* list, struct ListNode* node, void** data); int ll_remove_prev(List* list, ListNode* node, void** data);
#endif #endif

View File

@ -5,16 +5,16 @@
#define Set List #define Set List
void set_init(struct Set* set, int (*match)(const void* a, const void* b), void set_init(Set* set, int (*match)(const void* a, const void* b),
void (*destroy)(void* data)); void (*destroy)(void* data));
void set_destroy(struct Set* set); void set_destroy(Set* set);
int set_insert(struct Set* set, const void* data); int set_insert(Set* set, const void* data);
int set_remove(struct Set* set, void** data); int set_remove(Set* set, void** data);
int set_union(struct Set* setu, const struct Set* a, const struct Set* b); int set_union(Set* setu, const Set* a, const Set* b);
int set_intersection(struct Set* seti, const struct Set* a, const struct Set* b); int set_intersection(Set* seti, const Set* a, const Set* b);
int set_difference(struct Set* setd, const struct Set* a, const struct Set* b); int set_difference(Set* setd, const Set* a, const Set* b);
int set_is_member(const struct Set* set, const void* data); int set_is_member(const Set* set, const void* data);
int set_is_subset(const struct Set* a, const struct Set* b); int set_is_subset(const Set* a, const Set* b);
int set_is_equal(const struct Set* a, const struct Set* b); int set_is_equal(const Set* a, const Set* b);
#endif #endif

View File

@ -5,10 +5,10 @@
#define Stack List #define Stack List
void stack_init(struct Stack* stack, void (*destroy)(void* data)); void stack_init(Stack* stack, void (*destroy)(void* data));
void stack_destroy(struct Stack* stack); void stack_destroy(Stack* stack);
int stack_push(struct Stack* stack, void *data); int stack_push(Stack* stack, void *data);
void *stack_peek(struct Stack *stack); void *stack_peek(Stack *stack);
int stack_pop(struct Stack *stack, void **data); int stack_pop(Stack *stack, void **data);
#endif #endif

View File

@ -4,21 +4,21 @@
#include "binarytree.h" #include "binarytree.h"
void bintree_init(struct BinTree *tree, void (*destroy)(void *data)) { void bintree_init(BinTree *tree, void (*destroy)(void *data)) {
tree->size = 0; tree->size = 0;
tree->destroy = destroy; tree->destroy = destroy;
tree->compare = NULL; tree->compare = NULL;
tree->root = NULL; tree->root = NULL;
} }
void bintree_destroy(struct BinTree *tree) { void bintree_destroy(BinTree *tree) {
bintree_rem_left(tree, NULL); bintree_rem_left(tree, NULL);
memset(tree, 0, sizeof(struct BinTree)); memset(tree, 0, sizeof(BinTree));
} }
int bintree_ins_left(struct BinTree *tree, struct BinTreeNode *node, void *data) { int bintree_ins_left(BinTree *tree, BinTreeNode *node, void *data) {
struct BinTreeNode *new_node; BinTreeNode *new_node;
struct BinTreeNode **pos; BinTreeNode **pos;
if (node == NULL) { if (node == NULL) {
if (tree->size > 0) { if (tree->size > 0) {
@ -32,7 +32,7 @@ int bintree_ins_left(struct BinTree *tree, struct BinTreeNode *node, void *data)
pos = &node->left; pos = &node->left;
} }
if ((new_node = malloc(sizeof(struct BinTreeNode))) == NULL) { if ((new_node = malloc(sizeof(BinTreeNode))) == NULL) {
return 2; return 2;
} }
@ -45,9 +45,9 @@ int bintree_ins_left(struct BinTree *tree, struct BinTreeNode *node, void *data)
return 0; return 0;
} }
int bintree_ins_right(struct BinTree *tree, struct BinTreeNode *node, void *data) { int bintree_ins_right(BinTree *tree, BinTreeNode *node, void *data) {
struct BinTreeNode *new_node; BinTreeNode *new_node;
struct BinTreeNode **pos; BinTreeNode **pos;
if (node == NULL) { if (node == NULL) {
if (tree->size > 0) { if (tree->size > 0) {
@ -61,7 +61,7 @@ int bintree_ins_right(struct BinTree *tree, struct BinTreeNode *node, void *data
pos = &node->right; pos = &node->right;
} }
if ((new_node = malloc(sizeof(struct BinTreeNode))) == NULL) { if ((new_node = malloc(sizeof(BinTreeNode))) == NULL) {
return 2; return 2;
} }
@ -74,12 +74,12 @@ int bintree_ins_right(struct BinTree *tree, struct BinTreeNode *node, void *data
return 0; return 0;
} }
void bintree_rem_left(struct BinTree *tree, struct BinTreeNode *node) { void bintree_rem_left(BinTree *tree, BinTreeNode *node) {
if (tree->size == 0) { if (tree->size == 0) {
return; return;
} }
struct BinTreeNode **pos; BinTreeNode **pos;
if (node == NULL) { if (node == NULL) {
pos = &tree->root; pos = &tree->root;
} else { } else {
@ -98,12 +98,12 @@ void bintree_rem_left(struct BinTree *tree, struct BinTreeNode *node) {
} }
} }
void bintree_rem_right(struct BinTree *tree, struct BinTreeNode *node) { void bintree_rem_right(BinTree *tree, BinTreeNode *node) {
if (tree->size == 0) { if (tree->size == 0) {
return; return;
} }
struct BinTreeNode **pos; BinTreeNode **pos;
if (node == NULL) { if (node == NULL) {
pos = &tree->root; pos = &tree->root;
} else { } else {
@ -122,7 +122,7 @@ void bintree_rem_right(struct BinTree *tree, struct BinTreeNode *node) {
} }
} }
int bintree_merge(struct BinTree *merge, struct BinTree *left, struct BinTree *right, void *data) { int bintree_merge(BinTree *merge, BinTree *left, BinTree *right, void *data) {
bintree_init(merge, left->destroy); bintree_init(merge, left->destroy);
if (bintree_ins_left(merge, NULL, data) != 0) { if (bintree_ins_left(merge, NULL, data) != 0) {
bintree_destroy(merge); bintree_destroy(merge);
@ -140,7 +140,7 @@ int bintree_merge(struct BinTree *merge, struct BinTree *left, struct BinTree *r
return 0; return 0;
} }
void print_node(char* prefix, struct BinTreeNode *node, int is_left, void (*pfunc)(void* data)) { void print_node(char* prefix, BinTreeNode *node, int is_left, void (*pfunc)(void* data)) {
if (node != NULL) { if (node != NULL) {
printf("%s%s", prefix, (is_left ? "├──" : "└──" )); printf("%s%s", prefix, (is_left ? "├──" : "└──" ));
pfunc(node->data); pfunc(node->data);
@ -158,6 +158,6 @@ void bintree_debug_pfunc_int(void* data) {
printf("%d\n", i); printf("%d\n", i);
} }
void bintree_debug_print(struct BinTree *tree) { void bintree_debug_print(BinTree *tree) {
print_node("", tree->root, 0, bintree_debug_pfunc_int); print_node("", tree->root, 0, bintree_debug_pfunc_int);
} }

View File

@ -3,29 +3,29 @@
#include "linkedlist.h" #include "linkedlist.h"
void ll_init(struct List* list, void (*destroy)(void *data)) { void ll_init(List* list, void (*destroy)(void *data)) {
list->size = 0; list->size = 0;
list->destroy = destroy; list->destroy = destroy;
list->head = NULL; list->head = NULL;
list->tail = NULL; list->tail = NULL;
} }
void ll_destroy(struct List* list) { void ll_destroy(List* list) {
void* data; void* data;
while (list->size > 0) { while (list->size > 0) {
if (ll_remove(list, list->tail, (void**)&data) == 0 && list->destroy != NULL) { if (ll_remove(list, list->tail, (void**)&data) == 0 && list->destroy != NULL) {
list->destroy(data); list->destroy(data);
} }
} }
memset(list, 0, sizeof(struct List)); memset(list, 0, sizeof(List));
} }
int ll_ins_next(struct List* list, struct ListNode* node, const void* data) { int ll_ins_next(List* list, ListNode* node, const void* data) {
struct ListNode* new_node; ListNode* new_node;
if (node == NULL && list->size != 0) { if (node == NULL && list->size != 0) {
return -1; return -1;
} }
if ((new_node = malloc(sizeof(struct ListNode))) == NULL) { if ((new_node = malloc(sizeof(ListNode))) == NULL) {
return -1; return -1;
} }
@ -50,12 +50,12 @@ int ll_ins_next(struct List* list, struct ListNode* node, const void* data) {
return 0; return 0;
} }
int ll_ins_prev(struct List* list, struct ListNode* node, const void* data) { int ll_ins_prev(List* list, ListNode* node, const void* data) {
struct ListNode* new_node; ListNode* new_node;
if (node == NULL && list->size != 0) { if (node == NULL && list->size != 0) {
return -1; return -1;
} }
if ((new_node = malloc(sizeof(struct ListNode))) == NULL) { if ((new_node = malloc(sizeof(ListNode))) == NULL) {
return -1; return -1;
} }
@ -80,7 +80,7 @@ int ll_ins_prev(struct List* list, struct ListNode* node, const void* data) {
return 0; return 0;
} }
int ll_remove(struct List* list, struct ListNode* node, void** data) { int ll_remove(List* list, ListNode* node, void** data) {
if (node == NULL || list->size == 0) { if (node == NULL || list->size == 0) {
return -1; return -1;
} }
@ -106,14 +106,14 @@ int ll_remove(struct List* list, struct ListNode* node, void** data) {
return 0; return 0;
} }
int ll_remove_next(struct List* list, struct ListNode* node, void** data) { int ll_remove_next(List* list, ListNode* node, void** data) {
if (node->next == NULL) { if (node->next == NULL) {
return -1; return -1;
} }
return ll_remove(list, node->next, data); return ll_remove(list, node->next, data);
} }
int ll_remove_prev(struct List* list, struct ListNode* node, void** data) { int ll_remove_prev(List* list, ListNode* node, void** data) {
if (node->prev == NULL) { if (node->prev == NULL) {
return -1; return -1;
} }

View File

@ -1,24 +1,24 @@
#include "set.h" #include "set.h"
void set_init(struct Set* set, int (*match)(const void* a, const void* b), void set_init(Set* set, int (*match)(const void* a, const void* b),
void (*destroy)(void* data)) { void (*destroy)(void* data)) {
ll_init(set, destroy); ll_init(set, destroy);
set->match = match; set->match = match;
} }
void set_destroy(struct Set* set) { void set_destroy(Set* set) {
ll_destroy(set); ll_destroy(set);
} }
int set_insert(struct Set* set, const void* data) { int set_insert(Set* set, const void* data) {
if (set_is_member(set, data)) { if (set_is_member(set, data)) {
return 1; return 1;
} }
return ll_ins_next(set, set->tail, data); return ll_ins_next(set, set->tail, data);
} }
int set_remove(struct Set* set, void** data) { int set_remove(Set* set, void** data) {
struct ListNode* node = NULL; ListNode* node = NULL;
for (node = set->head; node != NULL; node = node->next) { for (node = set->head; node != NULL; node = node->next) {
if (set->match(*data, node->data)) { if (set->match(*data, node->data)) {
@ -32,8 +32,8 @@ int set_remove(struct Set* set, void** data) {
return ll_remove_next(set, node, data); return ll_remove_next(set, node, data);
} }
int set_union(struct Set* setu, const struct Set* a, const struct Set* b) { int set_union(Set* setu, const Set* a, const Set* b) {
struct ListNode* node; ListNode* node;
void* data; void* data;
set_init(setu, a->match, NULL); set_init(setu, a->match, NULL);
@ -59,8 +59,8 @@ int set_union(struct Set* setu, const struct Set* a, const struct Set* b) {
return 0; return 0;
} }
int set_intersection(struct Set* seti, const struct Set* a, const struct Set* b) { int set_intersection(Set* seti, const Set* a, const Set* b) {
struct ListNode* node; ListNode* node;
void* data; void* data;
set_init(seti, a->match, NULL); set_init(seti, a->match, NULL);
@ -77,8 +77,8 @@ int set_intersection(struct Set* seti, const struct Set* a, const struct Set* b)
return 0; return 0;
} }
int set_difference(struct Set* setd, const struct Set* a, const struct Set* b) { int set_difference(Set* setd, const Set* a, const Set* b) {
struct ListNode* node; ListNode* node;
void* data; void* data;
set_init(setd, a->match, NULL); set_init(setd, a->match, NULL);
@ -95,8 +95,8 @@ int set_difference(struct Set* setd, const struct Set* a, const struct Set* b) {
return 0; return 0;
} }
int set_is_member(const struct Set* set, const void* data) { int set_is_member(const Set* set, const void* data) {
for (struct ListNode* node = set->head; node != NULL; node = node->next) { for (ListNode* node = set->head; node != NULL; node = node->next) {
if (set->match(data, node->data)) { if (set->match(data, node->data)) {
return 1; return 1;
} }
@ -104,11 +104,11 @@ int set_is_member(const struct Set* set, const void* data) {
return 0; return 0;
} }
int set_is_subset(const struct Set* a, const struct Set* b) { int set_is_subset(const Set* a, const Set* b) {
if (a->size > b->size) { if (a->size > b->size) {
return 0; return 0;
} }
for (struct ListNode* node = a->head; node != NULL; node = node->next) { for (ListNode* node = a->head; node != NULL; node = node->next) {
if (!set_is_member(b, node->data)) { if (!set_is_member(b, node->data)) {
return 0; return 0;
} }
@ -116,7 +116,7 @@ int set_is_subset(const struct Set* a, const struct Set* b) {
return 1; return 1;
} }
int set_is_equal(const struct Set* a, const struct Set* b) { int set_is_equal(const Set* a, const Set* b) {
if (a->size == b->size) { if (a->size == b->size) {
return 0; return 0;
} }

View File

@ -1,14 +1,14 @@
#include "stack.h" #include "stack.h"
void stack_init(struct Stack* stack, void (*destroy)(void* data)) { void stack_init(Stack* stack, void (*destroy)(void* data)) {
ll_init(stack, destroy); ll_init(stack, destroy);
} }
void stack_destroy(struct Stack* stack) { void stack_destroy(Stack* stack) {
ll_destroy(stack); ll_destroy(stack);
} }
int stack_push(struct Stack* stack, void *data) { int stack_push(Stack* stack, void *data) {
if (stack->size == 0) { if (stack->size == 0) {
return ll_ins_next(stack, NULL, data); return ll_ins_next(stack, NULL, data);
} else { } else {
@ -16,10 +16,10 @@ int stack_push(struct Stack* stack, void *data) {
} }
} }
void *stack_peek(struct Stack *stack) { void *stack_peek(Stack *stack) {
return stack->tail == NULL ? NULL : stack->tail->data; return stack->tail == NULL ? NULL : stack->tail->data;
} }
int stack_pop(struct Stack *stack, void **data) { int stack_pop(Stack *stack, void **data) {
return ll_remove(stack, stack->tail, data); return ll_remove(stack, stack->tail, data);
} }

View File

@ -6,8 +6,8 @@
#include "stack.h" #include "stack.h"
#include "binarytree.h" #include "binarytree.h"
void print_ll(struct List* list) { void print_ll(List* list) {
for (struct ListNode* node = list->head; node != NULL; node = node->next) { for (ListNode* node = list->head; node != NULL; node = node->next) {
printf(" %d", *((int*)node->data)); printf(" %d", *((int*)node->data));
} }
printf("\n"); printf("\n");
@ -15,7 +15,7 @@ void print_ll(struct List* list) {
void test_ll() { void test_ll() {
printf("\n--- LIST TEST ---\n"); printf("\n--- LIST TEST ---\n");
struct List* list = malloc(sizeof(struct List)); List* list = malloc(sizeof(List));
ll_init(list, NULL); ll_init(list, NULL);
int i = 1; int i = 1;
@ -26,13 +26,13 @@ void test_ll() {
ll_ins_next(list, list->tail, (void*)&j); ll_ins_next(list, list->tail, (void*)&j);
ll_ins_next(list, list->tail, (void*)&k); ll_ins_next(list, list->tail, (void*)&k);
printf("struct List: "); printf("List: ");
print_ll(list); print_ll(list);
void* data; void* data;
ll_remove_next(list, list->head, &data); ll_remove_next(list, list->head, &data);
printf("struct List: "); printf("List: ");
print_ll(list); print_ll(list);
printf("Removed: %d\n", *((int*)data)); printf("Removed: %d\n", *((int*)data));
@ -46,7 +46,7 @@ int int_match(const void* a, const void* b) {
void test_set() { void test_set() {
printf("\n--- SET TEST ---\n"); printf("\n--- SET TEST ---\n");
struct Set* set = malloc(sizeof(struct Set)); Set* set = malloc(sizeof(Set));
set_init(set, int_match, NULL); set_init(set, int_match, NULL);
int i = 1; int i = 1;
@ -60,22 +60,22 @@ void test_set() {
int i2 = 1; int i2 = 1;
int j2 = 4; int j2 = 4;
struct Set* set2 = malloc(sizeof(struct Set)); Set* set2 = malloc(sizeof(Set));
set_init(set2, int_match, NULL); set_init(set2, int_match, NULL);
set_insert(set2, (void*)&i2); set_insert(set2, (void*)&i2);
set_insert(set2, (void*)&j2); set_insert(set2, (void*)&j2);
printf("struct Set 1:"); printf("Set 1:");
print_ll(set); print_ll(set);
printf("struct Set 2:"); printf("Set 2:");
print_ll(set2); print_ll(set2);
printf("\n"); printf("\n");
struct Set* set_u = malloc(sizeof(struct Set)); Set* set_u = malloc(sizeof(Set));
struct Set* set_i = malloc(sizeof(struct Set)); Set* set_i = malloc(sizeof(Set));
struct Set* set_d = malloc(sizeof(struct Set)); Set* set_d = malloc(sizeof(Set));
set_union(set_u, set, set2); set_union(set_u, set, set2);
printf("Union:"); printf("Union:");
@ -103,13 +103,13 @@ void test_set() {
void test_stack() { void test_stack() {
printf("\n--- STACK TEST ---\n"); printf("\n--- STACK TEST ---\n");
struct Stack *stack = malloc(sizeof(struct Stack)); Stack *stack = malloc(sizeof(Stack));
stack_init(stack, NULL); stack_init(stack, NULL);
int a = 1, b = 2; int a = 1, b = 2;
stack_push(stack, &a); stack_push(stack, &a);
stack_push(stack, &b); stack_push(stack, &b);
printf("struct Stack size: %lu\n", stack->size); printf("Stack size: %lu\n", stack->size);
int *p = NULL; int *p = NULL;
stack_pop(stack, (void **)&p); stack_pop(stack, (void **)&p);
@ -117,14 +117,14 @@ void test_stack() {
stack_pop(stack, (void **)&p); stack_pop(stack, (void **)&p);
printf("a = %d\n", *p); printf("a = %d\n", *p);
printf("struct Stack size: %lu\n", stack->size); printf("Stack size: %lu\n", stack->size);
stack_destroy(stack); stack_destroy(stack);
} }
void test_bintree() { void test_bintree() {
printf("\n--- BINARY TREE TEST ---\n"); printf("\n--- BINARY TREE TEST ---\n");
struct BinTree *tree = malloc(sizeof(struct BinTree)); BinTree *tree = malloc(sizeof(BinTree));
bintree_init(tree, NULL); bintree_init(tree, NULL);
int root = 0; int root = 0;