+#include <assert.h>
#include "mem.h"
#include "rbt.h"
/* rbt_t */
static void rbt_free(void* v_tree){
rbt_t* tree = (rbt_t*) v_tree;
- if(tree && tree->root) mem_release(tree->root);
+ assert(NULL != tree);
+ if(tree->root) mem_release(tree->root);
}
rbt_t* rbt_new(comparator_t comparator){
rbt_t* tree = mem_allocate(sizeof(rbt_t), &rbt_free);
/* rbt_node_t */
static void rbt_node_free(void* v_node){
rbt_node_t* node = (rbt_node_t*) v_node;
- if(node){
- mem_release(node->contents);
- if(node->left) mem_release(node->left);
- if(node->right) mem_release(node->right);
- }
+ assert(NULL != node);
+ mem_release(node->contents);
+ if(node->left) mem_release(node->left);
+ if(node->right) mem_release(node->right);
}
rbt_node_t* rbt_node_new(void* contents){
rbt_node_t* node = mem_allocate(sizeof(rbt_node_t), &rbt_node_free);
rbt_node_t* ret = NULL;
if(node){
int c = tree->comp(value, node->contents);
- if(c == 0) ret = node;
+ if (c < 0) ret = rbt_lookup_node(tree, node->left, value);
else if(c > 0) ret = rbt_lookup_node(tree, node->right, value);
- else if(c < 0) ret = rbt_lookup_node(tree, node->left, value);
+ else ret = node;
}
return ret;
}
static void rbt_rotate(rbt_t* tree, rbt_node_t* node, direction_t direction){
rbt_node_t* edon = (direction == LEFT) ? node->right : node->left;
- if(edon){
- rbt_node_t** edon_side = (direction == LEFT ? &(edon->left) : &(edon->right));
- rbt_node_t** node_side = (direction == LEFT ? &(node->right) : &(node->left));
- rbt_node_replace(tree, node, edon);
- *node_side = *edon_side; //safe to overwrite; points to edon
- if(*edon_side) (*edon_side)->parent = node;
- *edon_side = node;
- node->parent = edon;
- } /* else rotation isn't allowed */
+ assert(NULL != edon);
+ rbt_node_t** edon_side = (direction == LEFT ? &(edon->left) : &(edon->right));
+ rbt_node_t** node_side = (direction == LEFT ? &(node->right) : &(node->left));
+ rbt_node_replace(tree, node, edon);
+ *node_side = *edon_side; //safe to overwrite; points to edon
+ if(*edon_side) (*edon_side)->parent = node;
+ *edon_side = node;
+ node->parent = edon;
}
static void rbt_ins_rebalance(rbt_t* tree, rbt_node_t* node, direction_t heavy_side){
rbt_node_t* parent = node->parent;
- rbt_node_t* grandparent = (parent ? parent->parent : NULL);
+ assert(NULL != parent);
+ rbt_node_t* grandparent = parent->parent;
rbt_rotate(tree, grandparent, (heavy_side == LEFT ? RIGHT : LEFT));
parent->color = BLACK;
grandparent->color = RED;
if(parent){
direction_t node_side = (node == parent->left ? LEFT : RIGHT);
rbt_node_t* sib = (node_side == LEFT ? parent->right : parent->left);
+ assert(NULL != sib);
//nibling: gender neutral term for niece or nephew.
- rbt_node_t* inside_nibling = sib ? (node_side == LEFT ? sib->left : sib->right) : NULL;
- rbt_node_t* outside_nibling = sib ? (node_side == LEFT ? sib->right : sib->left) : NULL;
+ rbt_node_t* inside_nibling = node_side == LEFT ? sib->left : sib->right;
+ rbt_node_t* outside_nibling = node_side == LEFT ? sib->right : sib->left;
if(RED == rbt_node_color(sib)){
//rotate so sib is black & recurse w/ new scenario
rbt_rotate(tree, parent, node_side);
parent->color = BLACK;
outside_nibling->color = BLACK;
}
- }else{
- node->color = BLACK; //TODO: verify this is necessary
}
}