#include #include #include #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define IS_LEFT_CHILD(p, c) ((p) && (c) && ((p)->b_left == (c))) #define IS_RIGHT_CHILD(p, c) ((p) && (c) && ((p)->b_right == (c))) static void rotate_left(btree_t *tree, btree_node_t *x) { btree_node_t *y = x->b_right; btree_node_t *p = x->b_parent; if (y->b_left) { y->b_left->b_parent = x; } x->b_right = y->b_left; if (!p) { tree->b_root = y; } else if (x == p->b_left) { p->b_left = y; } else { p->b_right = y; } x->b_parent = y; y->b_left = x; y->b_parent = p; x->b_bfactor = x->b_bfactor - 1 - MAX(y->b_bfactor, 0); p = y; while (p) { p->b_bfactor = p->b_bfactor - 1 + MIN(y->b_bfactor, 0); x = p; p = p->b_parent; } } static void rotate_right(btree_t *tree, btree_node_t *y) { btree_node_t *x = y->b_left; btree_node_t *p = y->b_parent; if (x->b_right) { x->b_right->b_parent = y; } y->b_left = x->b_right; if (!p) { tree->b_root = x; } else if (x == p->b_left) { p->b_left = x; } else { p->b_right = x; } y->b_parent = x; x->b_right = y; x->b_parent = p; y->b_bfactor = y->b_bfactor + 1 - MIN(x->b_bfactor, 0); p = x; while (p) { p->b_bfactor = x->b_bfactor + 1 + MAX(y->b_bfactor, 0); y = p; } } static void rotate_double_left(btree_t *tree, btree_node_t *z) { btree_node_t *x = z->b_right; btree_node_t *y = x->b_left; rotate_right(tree, x); rotate_left(tree, z); } static void rotate_double_right(btree_t *tree, btree_node_t *z) { btree_node_t *x = z->b_left; btree_node_t *y = x->b_right; rotate_left(tree, x); rotate_right(tree, z); } static void insert_fixup(btree_t *tree, btree_node_t *w) { btree_node_t *z = NULL, *y = NULL, *x = NULL; z = w; while (z) { if (z->b_bfactor >= -1 && z->b_bfactor <= 1) { goto next_ancestor; } if (IS_LEFT_CHILD(z, y)) { if (IS_LEFT_CHILD(y, x)) { rotate_right(tree, z); } else { rotate_double_right(tree, z); } } else { if (IS_LEFT_CHILD(y, x)) { rotate_double_left(tree, z); } else { rotate_left(tree, z); } } next_ancestor: x = y; y = z; z = z->b_parent; } } void btree_insert(btree_t *tree, btree_node_t *node) { if (!tree->b_root) { tree->b_root = node; node->b_parent = NULL; return; } btree_node_t *cur = tree->b_root; while (1) { btree_node_t **nextp = NULL; int bfactor_diff = 0; if (node->b_key >= cur->b_key) { nextp = &cur->b_right; bfactor_diff = 1; } else { nextp = &cur->b_left; bfactor_diff = -1; } cur->b_bfactor = cur->b_bfactor + bfactor_diff; if (*nextp) { cur = *nextp; } else { node->b_parent = cur; *nextp = node; break; } } node->b_bfactor = 0; insert_fixup(tree, node); } void btree_delete(btree_t *tree, btree_node_t *node) { }