From: Elias Fleckenstein Date: Fri, 24 Sep 2021 12:33:18 +0000 (+0200) Subject: Add binary tree traversion X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=0a84db35735a112a12f026f871a730706aff1aeb;p=dragonstd.git Add binary tree traversion --- diff --git a/bintree.c b/bintree.c index 6587e12..f21403a 100644 --- a/bintree.c +++ b/bintree.c @@ -2,6 +2,12 @@ #include #include "bintree.h" +typedef struct +{ + BintreeTraversionFunction func; + void *arg; +} BintreeFreeData; + static int bintree_compare_mem(void *v1, void *v2, Bintree *tree) { return memcmp(v1, v2, tree->key_size); @@ -46,22 +52,49 @@ void bintree_add_node(Bintree *tree, BintreeNode **nodeptr, void *key, void *val (*nodeptr)->left = (*nodeptr)->right = NULL; } -static void free_recursive(BintreeNode *node, BintreeFreeFunction func, void *arg) +static void bintree_free(BintreeNode *node, void *arg) { - if (node) { - free_recursive(node->left, func, arg); - free_recursive(node->right, func, arg); - free(node->key); - if (func) - func(node->value, arg); - free(node); - } + BintreeFreeData *fdata = arg; + + if (fdata->func) + fdata->func(node, fdata->arg); + + free(node->key); + free(node); } -void bintree_clear(Bintree *tree, BintreeFreeFunction func, void *arg) +void bintree_clear(Bintree *tree, BintreeTraversionFunction func, void *arg) { if (tree) { - free_recursive(tree->root, func, arg); + BintreeFreeData fdata = { + .func = func, + .arg = arg, + }; + + bintree_traverse(tree, BTT_POSTORDER, &bintree_free, &fdata); tree->root = NULL; } } + +static void traverse_recursive(BintreeNode *node, BintreeTraversion traversion, BintreeTraversionFunction func, void *arg) +{ + if (node) { + if (traversion == BTT_PREORDER) + func(node, arg); + + traverse_recursive(node->left, traversion, func, arg); + + if (traversion == BTT_INORDER) + func(node, arg); + + traverse_recursive(node->right, traversion, func, arg); + + if (traversion == BTT_POSTORDER) + func(node, arg); + } +} + +void bintree_traverse(Bintree *tree, BintreeTraversion traversion, BintreeTraversionFunction func, void *arg) +{ + traverse_recursive(tree->root, traversion, func, arg); +} diff --git a/bintree.h b/bintree.h index 9dd0cfa..36099f1 100644 --- a/bintree.h +++ b/bintree.h @@ -5,9 +5,6 @@ struct Bintree; -typedef int (*BintreeComparator)(void *v1, void *v2, struct Bintree *tree); -typedef void (*BintreeFreeFunction)(void *value, void *arg); - typedef struct BintreeNode { void *key; @@ -16,6 +13,9 @@ typedef struct BintreeNode struct BintreeNode *right; } BintreeNode; +typedef int (*BintreeComparator)(void *v1, void *v2, struct Bintree *tree); +typedef void (*BintreeTraversionFunction)(BintreeNode *node, void *arg); + typedef struct Bintree { BintreeNode *root; @@ -23,9 +23,17 @@ typedef struct Bintree BintreeComparator cmp; } Bintree; +typedef enum +{ + BTT_PREORDER, + BTT_INORDER, + BTT_POSTORDER, +} BintreeTraversion; + Bintree bintree_create(size_t key_size, BintreeComparator cmp); BintreeNode **bintree_search(Bintree *tree, void *key); void bintree_add_node(Bintree *tree, BintreeNode **nodeptr, void *key, void *value); -void bintree_clear(Bintree *tree, BintreeFreeFunction func, void *arg); +void bintree_traverse(Bintree *tree, BintreeTraversion traversion, BintreeTraversionFunction func, void *arg); +void bintree_clear(Bintree *tree, BintreeTraversionFunction func, void *arg); #endif