init
This commit is contained in:
commit
86be1e8de5
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
cmake*
|
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
2
.idea/libfputs.iml
generated
Normal file
2
.idea/libfputs.iml
generated
Normal file
@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module classpath="CMake" type="CPP_MODULE" version="4" />
|
4
.idea/misc.xml
generated
Normal file
4
.idea/misc.xml
generated
Normal file
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
|
||||
</project>
|
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/libfputs.iml" filepath="$PROJECT_DIR$/.idea/libfputs.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
21
CMakeLists.txt
Normal file
21
CMakeLists.txt
Normal file
@ -0,0 +1,21 @@
|
||||
cmake_minimum_required(VERSION 3.17)
|
||||
project(flint C)
|
||||
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
include_directories(include)
|
||||
|
||||
set(SOURCES
|
||||
src/linkedlist.c
|
||||
src/set.c
|
||||
src/stack.c
|
||||
src/binarytree.c
|
||||
)
|
||||
|
||||
add_library(flint ${SOURCES})
|
||||
|
||||
if(${CMAKE_PROJECT_NAME} STREQUAL flint)
|
||||
add_executable(tests tests/tests.c)
|
||||
target_include_directories(tests PRIVATE include)
|
||||
target_link_libraries(tests flint)
|
||||
endif()
|
||||
|
13
LICENSE
Normal file
13
LICENSE
Normal file
@ -0,0 +1,13 @@
|
||||
Copyright 2021 Evan Burkey <evan@burkey.co>
|
||||
|
||||
Permission to use, copy, modify, and distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
3
README.md
Normal file
3
README.md
Normal file
@ -0,0 +1,3 @@
|
||||
# flint
|
||||
|
||||
My personal library of common C data structures and algorithms.
|
31
include/binarytree.h
Normal file
31
include/binarytree.h
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef LIBFLINT_BINARY_TREE_H
|
||||
#define LIBFLINT_BINARY_TREE_H
|
||||
|
||||
struct BinTreeNode {
|
||||
void *data;
|
||||
struct BinTreeNode *left;
|
||||
struct BinTreeNode *right;
|
||||
};
|
||||
|
||||
struct BinTree {
|
||||
int size;
|
||||
|
||||
int (*compare)(const void *a, const void *b);
|
||||
void (*destroy)(void *data);
|
||||
|
||||
struct BinTreeNode *root;
|
||||
};
|
||||
|
||||
void bintree_init(struct BinTree *tree, void (*destroy)(void *data));
|
||||
void bintree_destroy(struct BinTree *tree);
|
||||
int bintree_ins_left(struct BinTree *tree, struct BinTreeNode *node, void *data);
|
||||
int bintree_ins_right(struct BinTree *tree, struct BinTreeNode *node, void *data);
|
||||
void bintree_rem_left(struct BinTree *tree, struct BinTreeNode *node);
|
||||
void bintree_rem_right(struct BinTree *tree, struct BinTreeNode *node);
|
||||
int bintree_merge(struct BinTree *merge, struct BinTree *left, struct BinTree *right, void *data);
|
||||
void bintree_debug_print(struct BinTree *tree);
|
||||
|
||||
#define bintree_is_eob(node) ((node) == NULL)
|
||||
#define bintree_is_leaf(node) ((node)->left == NULL && (node)->right == NULL)
|
||||
|
||||
#endif
|
30
include/linkedlist.h
Normal file
30
include/linkedlist.h
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef LIBFLINT_LL_H
|
||||
#define LIBFLINT_LL_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
struct ListNode {
|
||||
void* data;
|
||||
struct ListNode* next;
|
||||
struct ListNode* prev;
|
||||
};
|
||||
|
||||
struct List {
|
||||
size_t size;
|
||||
|
||||
void (*destroy)(void* data);
|
||||
int (*match)(const void* a, const void* b);
|
||||
|
||||
struct ListNode* head;
|
||||
struct ListNode* tail;
|
||||
};
|
||||
|
||||
void ll_init(struct List* list, void (*destroy)(void *data));
|
||||
void ll_destroy(struct List* list);
|
||||
int ll_ins_next(struct List* list, struct ListNode* node, const void* data);
|
||||
int ll_ins_prev(struct List* list, struct ListNode* node, const void* data);
|
||||
int ll_remove(struct List* list, struct ListNode* node, void** data);
|
||||
int ll_remove_next(struct List* list, struct ListNode* node, void** data);
|
||||
int ll_remove_prev(struct List* list, struct ListNode* node, void** data);
|
||||
|
||||
#endif
|
20
include/set.h
Normal file
20
include/set.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef LIBFLINT_SET_H
|
||||
#define LIBFLINT_SET_H
|
||||
|
||||
#include "linkedlist.h"
|
||||
|
||||
#define Set List
|
||||
|
||||
void set_init(struct Set* set, int (*match)(const void* a, const void* b),
|
||||
void (*destroy)(void* data));
|
||||
void set_destroy(struct Set* set);
|
||||
int set_insert(struct Set* set, const void* data);
|
||||
int set_remove(struct Set* set, void** data);
|
||||
int set_union(struct Set* setu, const struct Set* a, const struct Set* b);
|
||||
int set_intersection(struct Set* seti, const struct Set* a, const struct Set* b);
|
||||
int set_difference(struct Set* setd, const struct Set* a, const struct Set* b);
|
||||
int set_is_member(const struct Set* set, const void* data);
|
||||
int set_is_subset(const struct Set* a, const struct Set* b);
|
||||
int set_is_equal(const struct Set* a, const struct Set* b);
|
||||
|
||||
#endif
|
14
include/stack.h
Normal file
14
include/stack.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef LIBFLINT_STACK_H
|
||||
#define LIBFLINT_STACK_H
|
||||
|
||||
#include "linkedlist.h"
|
||||
|
||||
#define Stack List
|
||||
|
||||
void stack_init(struct Stack* stack, void (*destroy)(void* data));
|
||||
void stack_destroy(struct Stack* stack);
|
||||
int stack_push(struct Stack* stack, void *data);
|
||||
void *stack_peek(struct Stack *stack);
|
||||
int stack_pop(struct Stack *stack, void **data);
|
||||
|
||||
#endif
|
163
src/binarytree.c
Normal file
163
src/binarytree.c
Normal file
@ -0,0 +1,163 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "binarytree.h"
|
||||
|
||||
void bintree_init(struct BinTree *tree, void (*destroy)(void *data)) {
|
||||
tree->size = 0;
|
||||
tree->destroy = destroy;
|
||||
tree->compare = NULL;
|
||||
tree->root = NULL;
|
||||
}
|
||||
|
||||
void bintree_destroy(struct BinTree *tree) {
|
||||
bintree_rem_left(tree, NULL);
|
||||
memset(tree, 0, sizeof(struct BinTree));
|
||||
}
|
||||
|
||||
int bintree_ins_left(struct BinTree *tree, struct BinTreeNode *node, void *data) {
|
||||
struct BinTreeNode *new_node;
|
||||
struct BinTreeNode **pos;
|
||||
|
||||
if (node == NULL) {
|
||||
if (tree->size > 0) {
|
||||
return 1;
|
||||
}
|
||||
pos = &tree->root;
|
||||
} else {
|
||||
if (node->left != NULL) {
|
||||
return -1;
|
||||
}
|
||||
pos = &node->left;
|
||||
}
|
||||
|
||||
if ((new_node = malloc(sizeof(struct BinTreeNode))) == NULL) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
new_node->data = data;
|
||||
new_node->left = NULL;
|
||||
new_node->right = NULL;
|
||||
*pos = new_node;
|
||||
|
||||
tree->size += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bintree_ins_right(struct BinTree *tree, struct BinTreeNode *node, void *data) {
|
||||
struct BinTreeNode *new_node;
|
||||
struct BinTreeNode **pos;
|
||||
|
||||
if (node == NULL) {
|
||||
if (tree->size > 0) {
|
||||
return 1;
|
||||
}
|
||||
pos = &tree->root;
|
||||
} else {
|
||||
if (node->right != NULL) {
|
||||
return -1;
|
||||
}
|
||||
pos = &node->right;
|
||||
}
|
||||
|
||||
if ((new_node = malloc(sizeof(struct BinTreeNode))) == NULL) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
new_node->data = data;
|
||||
new_node->left = NULL;
|
||||
new_node->right = NULL;
|
||||
*pos = new_node;
|
||||
|
||||
tree->size += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void bintree_rem_left(struct BinTree *tree, struct BinTreeNode *node) {
|
||||
if (tree->size == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct BinTreeNode **pos;
|
||||
if (node == NULL) {
|
||||
pos = &tree->root;
|
||||
} else {
|
||||
pos = &node->left;
|
||||
}
|
||||
|
||||
if (*pos != NULL) {
|
||||
bintree_rem_left(tree, *pos);
|
||||
bintree_rem_right(tree, *pos);
|
||||
if (tree->destroy != NULL) {
|
||||
tree->destroy((*pos)->data);
|
||||
}
|
||||
free(*pos);
|
||||
*pos = NULL;
|
||||
tree->size -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
void bintree_rem_right(struct BinTree *tree, struct BinTreeNode *node) {
|
||||
if (tree->size == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct BinTreeNode **pos;
|
||||
if (node == NULL) {
|
||||
pos = &tree->root;
|
||||
} else {
|
||||
pos = &node->right;
|
||||
}
|
||||
|
||||
if (*pos != NULL) {
|
||||
bintree_rem_left(tree, *pos);
|
||||
bintree_rem_right(tree, *pos);
|
||||
if (tree->destroy != NULL) {
|
||||
tree->destroy((*pos)->data);
|
||||
}
|
||||
free(*pos);
|
||||
*pos = NULL;
|
||||
tree->size -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
int bintree_merge(struct BinTree *merge, struct BinTree *left, struct BinTree *right, void *data) {
|
||||
bintree_init(merge, left->destroy);
|
||||
if (bintree_ins_left(merge, NULL, data) != 0) {
|
||||
bintree_destroy(merge);
|
||||
return -1;
|
||||
}
|
||||
|
||||
merge->root->left = left->root;
|
||||
merge->root->right = right->root;
|
||||
|
||||
left->root = NULL;
|
||||
left->size = 0;
|
||||
right->root = NULL;
|
||||
right->size = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void print_node(char* prefix, struct BinTreeNode *node, int is_left, void (*pfunc)(void* data)) {
|
||||
if (node != NULL) {
|
||||
printf("%s%s", prefix, (is_left ? "├──" : "└──" ));
|
||||
pfunc(node->data);
|
||||
char new_prefix[64];
|
||||
memset(new_prefix, 0, 64);
|
||||
strcat(new_prefix, prefix);
|
||||
strcat(new_prefix, (is_left == 1 ? "│ " : " "));
|
||||
print_node(new_prefix, node->left, 1, pfunc);
|
||||
print_node(new_prefix, node->right, 0, pfunc);
|
||||
}
|
||||
}
|
||||
|
||||
void bintree_debug_pfunc_int(void* data) {
|
||||
int i = *((int*)data);
|
||||
printf("%d\n", i);
|
||||
}
|
||||
|
||||
void bintree_debug_print(struct BinTree *tree) {
|
||||
print_node("", tree->root, 0, bintree_debug_pfunc_int);
|
||||
}
|
122
src/linkedlist.c
Normal file
122
src/linkedlist.c
Normal file
@ -0,0 +1,122 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "linkedlist.h"
|
||||
|
||||
void ll_init(struct List* list, void (*destroy)(void *data)) {
|
||||
list->size = 0;
|
||||
list->destroy = destroy;
|
||||
list->head = NULL;
|
||||
list->tail = NULL;
|
||||
}
|
||||
|
||||
void ll_destroy(struct List* list) {
|
||||
void* data;
|
||||
while (list->size > 0) {
|
||||
if (ll_remove(list, list->tail, (void**)&data) == 0 && list->destroy != NULL) {
|
||||
list->destroy(data);
|
||||
}
|
||||
}
|
||||
memset(list, 0, sizeof(struct List));
|
||||
}
|
||||
|
||||
int ll_ins_next(struct List* list, struct ListNode* node, const void* data) {
|
||||
struct ListNode* new_node;
|
||||
if (node == NULL && list->size != 0) {
|
||||
return -1;
|
||||
}
|
||||
if ((new_node = malloc(sizeof(struct ListNode))) == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
new_node->data = (void*)data;
|
||||
if (list->size == 0) {
|
||||
list->head = new_node;
|
||||
list->head->prev = NULL;
|
||||
list->head->next = NULL;
|
||||
list->tail = new_node;
|
||||
} else {
|
||||
new_node->next = node->next;
|
||||
new_node->prev = node;
|
||||
if (node->next == NULL) {
|
||||
list->tail = new_node;
|
||||
} else {
|
||||
node->next->prev = new_node;
|
||||
}
|
||||
node->next = new_node;
|
||||
}
|
||||
|
||||
list->size++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ll_ins_prev(struct List* list, struct ListNode* node, const void* data) {
|
||||
struct ListNode* new_node;
|
||||
if (node == NULL && list->size != 0) {
|
||||
return -1;
|
||||
}
|
||||
if ((new_node = malloc(sizeof(struct ListNode))) == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
new_node->data = (void*)data;
|
||||
if (list->size == 0) {
|
||||
list->head = new_node;
|
||||
list->head->prev = NULL;
|
||||
list->head->next = NULL;
|
||||
list->tail = new_node;
|
||||
} else {
|
||||
new_node->next = node;
|
||||
new_node->prev = node->prev;
|
||||
if (node->prev == NULL) {
|
||||
list->head = new_node;
|
||||
} else {
|
||||
node->prev->next = new_node;
|
||||
}
|
||||
node->prev = new_node;
|
||||
}
|
||||
|
||||
list->size++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ll_remove(struct List* list, struct ListNode* node, void** data) {
|
||||
if (node == NULL || list->size == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*data = node->data;
|
||||
if (node == list->head) {
|
||||
list->head = node->next;
|
||||
if (list->head == NULL) {
|
||||
list->tail = NULL;
|
||||
} else {
|
||||
node->next->prev = NULL;
|
||||
}
|
||||
} else {
|
||||
node->prev->next = node->next;
|
||||
if (node->next == NULL) {
|
||||
list->tail = node->prev;
|
||||
} else {
|
||||
node->next->prev = node->prev;
|
||||
}
|
||||
}
|
||||
free(node);
|
||||
list->size--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ll_remove_next(struct List* list, struct ListNode* node, void** data) {
|
||||
if (node->next == NULL) {
|
||||
return -1;
|
||||
}
|
||||
return ll_remove(list, node->next, data);
|
||||
}
|
||||
|
||||
int ll_remove_prev(struct List* list, struct ListNode* node, void** data) {
|
||||
if (node->prev == NULL) {
|
||||
return -1;
|
||||
}
|
||||
return ll_remove(list, node->prev, data);
|
||||
}
|
||||
|
124
src/set.c
Normal file
124
src/set.c
Normal file
@ -0,0 +1,124 @@
|
||||
#include "set.h"
|
||||
|
||||
void set_init(struct Set* set, int (*match)(const void* a, const void* b),
|
||||
void (*destroy)(void* data)) {
|
||||
ll_init(set, destroy);
|
||||
set->match = match;
|
||||
}
|
||||
|
||||
void set_destroy(struct Set* set) {
|
||||
ll_destroy(set);
|
||||
}
|
||||
|
||||
int set_insert(struct Set* set, const void* data) {
|
||||
if (set_is_member(set, data)) {
|
||||
return 1;
|
||||
}
|
||||
return ll_ins_next(set, set->tail, data);
|
||||
}
|
||||
|
||||
int set_remove(struct Set* set, void** data) {
|
||||
struct ListNode* node = NULL;
|
||||
|
||||
for (node = set->head; node != NULL; node = node->next) {
|
||||
if (set->match(*data, node->data)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (node == NULL) {
|
||||
return -1;
|
||||
}
|
||||
return ll_remove_next(set, node, data);
|
||||
}
|
||||
|
||||
int set_union(struct Set* setu, const struct Set* a, const struct Set* b) {
|
||||
struct ListNode* node;
|
||||
void* data;
|
||||
|
||||
set_init(setu, a->match, NULL);
|
||||
for (node = a->head; node != NULL; node = node->next) {
|
||||
data = node->data;
|
||||
if (ll_ins_next(setu, setu->tail, data) != 0) {
|
||||
set_destroy(setu);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
for (node = b->head; node != NULL; node = node->next) {
|
||||
if (set_is_member(a, node->data)) {
|
||||
continue;
|
||||
}
|
||||
data = node->data;
|
||||
if (ll_ins_next(setu, setu->tail, data) != 0) {
|
||||
set_destroy(setu);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_intersection(struct Set* seti, const struct Set* a, const struct Set* b) {
|
||||
struct ListNode* node;
|
||||
void* data;
|
||||
|
||||
set_init(seti, a->match, NULL);
|
||||
for (node = a->head; node != NULL; node = node->next) {
|
||||
data = node->data;
|
||||
if (set_is_member(b, data)) {
|
||||
if (ll_ins_next(seti, seti->tail, data)) {
|
||||
set_destroy(seti);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_difference(struct Set* setd, const struct Set* a, const struct Set* b) {
|
||||
struct ListNode* node;
|
||||
void* data;
|
||||
|
||||
set_init(setd, a->match, NULL);
|
||||
for (node = a->head; node != NULL; node = node->next) {
|
||||
data = node->data;
|
||||
if (!set_is_member(b, data)) {
|
||||
if (ll_ins_next(setd, setd->tail, data)) {
|
||||
set_destroy(setd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_is_member(const struct Set* set, const void* data) {
|
||||
for (struct ListNode* node = set->head; node != NULL; node = node->next) {
|
||||
if (set->match(data, node->data)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_is_subset(const struct Set* a, const struct Set* b) {
|
||||
if (a->size > b->size) {
|
||||
return 0;
|
||||
}
|
||||
for (struct ListNode* node = a->head; node != NULL; node = node->next) {
|
||||
if (!set_is_member(b, node->data)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int set_is_equal(const struct Set* a, const struct Set* b) {
|
||||
if (a->size == b->size) {
|
||||
return 0;
|
||||
}
|
||||
return set_is_subset(a, b);
|
||||
}
|
25
src/stack.c
Normal file
25
src/stack.c
Normal file
@ -0,0 +1,25 @@
|
||||
#include "stack.h"
|
||||
|
||||
void stack_init(struct Stack* stack, void (*destroy)(void* data)) {
|
||||
ll_init(stack, destroy);
|
||||
}
|
||||
|
||||
void stack_destroy(struct Stack* stack) {
|
||||
ll_destroy(stack);
|
||||
}
|
||||
|
||||
int stack_push(struct Stack* stack, void *data) {
|
||||
if (stack->size == 0) {
|
||||
return ll_ins_next(stack, NULL, data);
|
||||
} else {
|
||||
return ll_ins_next(stack, stack->tail, data);
|
||||
}
|
||||
}
|
||||
|
||||
void *stack_peek(struct Stack *stack) {
|
||||
return stack->tail == NULL ? NULL : stack->tail->data;
|
||||
}
|
||||
|
||||
int stack_pop(struct Stack *stack, void **data) {
|
||||
return ll_remove(stack, stack->tail, data);
|
||||
}
|
155
tests/tests.c
Normal file
155
tests/tests.c
Normal file
@ -0,0 +1,155 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "linkedlist.h"
|
||||
#include "set.h"
|
||||
#include "stack.h"
|
||||
#include "binarytree.h"
|
||||
|
||||
void print_ll(struct List* list) {
|
||||
for (struct ListNode* node = list->head; node != NULL; node = node->next) {
|
||||
printf(" %d", *((int*)node->data));
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void test_ll() {
|
||||
printf("\n--- LIST TEST ---\n");
|
||||
struct List* list = malloc(sizeof(struct List));
|
||||
ll_init(list, NULL);
|
||||
|
||||
int i = 1;
|
||||
int j = 2;
|
||||
int k = 4;
|
||||
|
||||
ll_ins_next(list, list->head, (void*)&i);
|
||||
ll_ins_next(list, list->tail, (void*)&j);
|
||||
ll_ins_next(list, list->tail, (void*)&k);
|
||||
|
||||
printf("struct List: ");
|
||||
print_ll(list);
|
||||
|
||||
void* data;
|
||||
ll_remove_next(list, list->head, &data);
|
||||
|
||||
printf("struct List: ");
|
||||
print_ll(list);
|
||||
printf("Removed: %d\n", *((int*)data));
|
||||
|
||||
ll_destroy(list);
|
||||
free(list);
|
||||
}
|
||||
|
||||
int int_match(const void* a, const void* b) {
|
||||
return *((int*)a) == *((int*)b);
|
||||
}
|
||||
|
||||
void test_set() {
|
||||
printf("\n--- SET TEST ---\n");
|
||||
struct Set* set = malloc(sizeof(struct Set));
|
||||
set_init(set, int_match, NULL);
|
||||
|
||||
int i = 1;
|
||||
int j = 2;
|
||||
int k = 2;
|
||||
|
||||
set_insert(set, (void*)&i);
|
||||
set_insert(set, (void*)&j);
|
||||
set_insert(set, (void*)&k);
|
||||
|
||||
int i2 = 1;
|
||||
int j2 = 4;
|
||||
|
||||
struct Set* set2 = malloc(sizeof(struct Set));
|
||||
set_init(set2, int_match, NULL);
|
||||
|
||||
set_insert(set2, (void*)&i2);
|
||||
set_insert(set2, (void*)&j2);
|
||||
|
||||
printf("struct Set 1:");
|
||||
print_ll(set);
|
||||
|
||||
printf("struct Set 2:");
|
||||
print_ll(set2);
|
||||
printf("\n");
|
||||
|
||||
struct Set* set_u = malloc(sizeof(struct Set));
|
||||
struct Set* set_i = malloc(sizeof(struct Set));
|
||||
struct Set* set_d = malloc(sizeof(struct Set));
|
||||
|
||||
set_union(set_u, set, set2);
|
||||
printf("Union:");
|
||||
print_ll(set_u);
|
||||
|
||||
set_difference(set_d, set, set2);
|
||||
printf("Difference:");
|
||||
print_ll(set_d);
|
||||
|
||||
set_intersection(set_i, set, set2);
|
||||
printf("Intersection:");
|
||||
print_ll(set_i);
|
||||
|
||||
set_destroy(set);
|
||||
set_destroy(set2);
|
||||
set_destroy(set_u);
|
||||
set_destroy(set_i);
|
||||
set_destroy(set_d);
|
||||
free(set);
|
||||
free(set2);
|
||||
free(set_u);
|
||||
free(set_i);
|
||||
free(set_d);
|
||||
}
|
||||
|
||||
void test_stack() {
|
||||
printf("\n--- STACK TEST ---\n");
|
||||
struct Stack *stack = malloc(sizeof(struct Stack));
|
||||
stack_init(stack, NULL);
|
||||
|
||||
int a = 1, b = 2;
|
||||
stack_push(stack, &a);
|
||||
stack_push(stack, &b);
|
||||
printf("struct Stack size: %lu\n", stack->size);
|
||||
|
||||
int *p = NULL;
|
||||
stack_pop(stack, (void **)&p);
|
||||
printf("b = %d\n", *p);
|
||||
|
||||
stack_pop(stack, (void **)&p);
|
||||
printf("a = %d\n", *p);
|
||||
printf("struct Stack size: %lu\n", stack->size);
|
||||
|
||||
stack_destroy(stack);
|
||||
}
|
||||
|
||||
void test_bintree() {
|
||||
printf("\n--- BINARY TREE TEST ---\n");
|
||||
struct BinTree *tree = malloc(sizeof(struct BinTree));
|
||||
bintree_init(tree, NULL);
|
||||
|
||||
int root = 0;
|
||||
int l1 = 1;
|
||||
int l2 = 2;
|
||||
int r1 = 12;
|
||||
int r2 = 200;
|
||||
|
||||
bintree_ins_left(tree, NULL, &root);
|
||||
bintree_ins_left(tree, tree->root, &l1);
|
||||
bintree_ins_left(tree, tree->root->left, &l2);
|
||||
bintree_ins_right(tree, tree->root->left, &r2);
|
||||
bintree_ins_right(tree, tree->root, &r1);
|
||||
bintree_ins_right(tree, tree->root->right, &r2);
|
||||
bintree_ins_left(tree, tree->root->right, &l1);
|
||||
|
||||
bintree_debug_print(tree);
|
||||
|
||||
bintree_destroy(tree);
|
||||
}
|
||||
|
||||
int main() {
|
||||
test_ll();
|
||||
test_set();
|
||||
test_stack();
|
||||
test_bintree();
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user