#include #include #include #include "bintree.h" #if 0 static int NIL_VALUE = 1; #endif static void* NIL_NODE = &NIL_NODE; static struct bintree_node *new_nil_node(struct bintree_node *parent); void bintree_new(struct bintree *t, bintree_cmp_func cmp, void *ctx) { t->root = new_nil_node(NULL); t->cmp = cmp; t->ctx = ctx; } static struct bintree_node *new_nil_node(struct bintree_node *parent) { struct bintree_node *node = (struct bintree_node*)calloc(1, sizeof(struct bintree_node)); if (!node) return NULL; node->value = NIL_NODE; node->parent = parent; node->left = NULL; node->right = NULL; return node; } static inline int is_nil(const struct bintree_node *node) { return node == NULL || node->value == NIL_NODE; } static int insert(struct bintree *t, struct bintree_node *root, void *value) { int cmp_res = 0; if (is_nil(root)) { root->left = new_nil_node(root); root->right = new_nil_node(root); if (!root->left || !root->right) { if (root->left) { free(root->left); root->left = NULL; } if (root->right) { free(root->right); root->right = NULL; } return -ENOMEM; } root->value = value; } else { cmp_res = t->cmp(root->value, value, t->ctx); if (cmp_res > 0) return insert(t, root->left, value); else if (cmp_res < 0) return insert(t, root->right, value); else return -EINVAL; } return 0; } int bintree_insert(struct bintree *t, void *value) { return insert(t, t->root, value); } static int _bintree_iterate(struct bintree_node *n, bintree_iter_cb cb, void *ctx) { int rv; if (is_nil(n)) return 0; else { if((rv = _bintree_iterate(n->left, cb, ctx)) != 0) return rv; if ((rv = cb(n->value, ctx)) != 0) return rv; if((rv = _bintree_iterate(n->right, cb, ctx)) != 0) return rv; } return 0; } int bintree_iterate(const struct bintree *t, bintree_iter_cb cb, void *ctx) { return _bintree_iterate(t->root, cb, ctx); } static void bintree_free_node(struct bintree_node *n) { if (n == NULL) return; if (n->value == NIL_NODE) { free(n); return; } n->value = NULL; bintree_free_node(n->left); bintree_free_node(n->right); free(n); } void bintree_free(struct bintree *t) { bintree_free_node(t->root); }