]> git.lizzy.rs Git - dragonstd.git/commitdiff
Add binary tree traversion
authorElias Fleckenstein <eliasfleckenstein@web.de>
Fri, 24 Sep 2021 12:33:18 +0000 (14:33 +0200)
committerElias Fleckenstein <eliasfleckenstein@web.de>
Fri, 24 Sep 2021 12:33:18 +0000 (14:33 +0200)
bintree.c
bintree.h

index 6587e12a7d6d72a72ab82720db642e385ce8109a..f21403ab0eab71f1781ab3981507463c9af802f3 100644 (file)
--- a/bintree.c
+++ b/bintree.c
@@ -2,6 +2,12 @@
 #include <stdlib.h>
 #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);
+}
index 9dd0cfa6c4e73a369310e40f632b8de113e80a04..36099f12930a14813c9c97b5a12a74d1157a4ed1 100644 (file)
--- 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