#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); }