/** * Travel subtree for find the value in preorder. */ _rbnode_t* _rb_tree_find_value(const _rb_tree_t* cpt_rb_tree, const _rbnode_t* cpt_root, const void* cpv_value) { bool_t b_result = false; assert(cpt_rb_tree != NULL); assert(cpv_value != NULL); assert(_rb_tree_is_inited(cpt_rb_tree)); if(cpt_root == NULL) { return NULL; } b_result = _GET_RB_TREE_TYPE_SIZE(cpt_rb_tree); _rb_tree_elem_compare_auxiliary(cpt_rb_tree, cpv_value, cpt_root->_pby_data, &b_result); if(b_result) { return _rb_tree_find_value(cpt_rb_tree, cpt_root->_pt_left, cpv_value); } b_result = _GET_RB_TREE_TYPE_SIZE(cpt_rb_tree); _rb_tree_elem_compare_auxiliary(cpt_rb_tree, cpt_root->_pby_data, cpv_value, &b_result); if(b_result) { return _rb_tree_find_value(cpt_rb_tree, cpt_root->_pt_right, cpv_value); } else { return (_rbnode_t*)cpt_root; } }
/** * Destroy the subtree with postorder traverse. */ _rbnode_t* _rb_tree_destroy_subtree(_rb_tree_t* pt_rb_tree, _rbnode_t* pt_root) { bool_t b_result = false; assert(pt_rb_tree != NULL); assert(_rb_tree_is_inited(pt_rb_tree) || _rb_tree_is_created(pt_rb_tree)); if(pt_root != NULL) { pt_root->_pt_left = _rb_tree_destroy_subtree(pt_rb_tree, pt_root->_pt_left); pt_root->_pt_right = _rb_tree_destroy_subtree(pt_rb_tree, pt_root->_pt_right); assert(pt_root->_pt_left == NULL && pt_root->_pt_right == NULL); b_result = _GET_RB_TREE_TYPE_SIZE(pt_rb_tree); _GET_RB_TREE_TYPE_DESTROY_FUNCTION(pt_rb_tree)(pt_root->_pby_data, &b_result); assert(b_result); _alloc_deallocate(&pt_rb_tree->_t_allocator, pt_root, _RB_TREE_NODE_SIZE(_GET_RB_TREE_TYPE_SIZE(pt_rb_tree)), 1); } return NULL; }
/** * Get data value referenced by iterator. */ void _rb_tree_iterator_get_value(_rb_tree_iterator_t it_iter, void* pv_value) { assert(pv_value != NULL); assert(_rb_tree_iterator_belong_to_rb_tree(_RB_TREE_ITERATOR_TREE(it_iter), it_iter)); assert(!_rb_tree_iterator_equal(it_iter, _rb_tree_end(_RB_TREE_ITERATOR_TREE(it_iter)))); /* char* */ if (strncmp(_GET_RB_TREE_TYPE_BASENAME(_RB_TREE_ITERATOR_TREE(it_iter)), _C_STRING_TYPE, _TYPE_NAME_SIZE) == 0) { *(char**)pv_value = (char*)string_c_str((string_t*)((_rbnode_t*)_RB_TREE_ITERATOR_COREPOS(it_iter))->_pby_data); } else { bool_t b_result = _GET_RB_TREE_TYPE_SIZE(_RB_TREE_ITERATOR_TREE(it_iter)); _GET_RB_TREE_TYPE_COPY_FUNCTION(_RB_TREE_ITERATOR_TREE(it_iter))( pv_value, ((_rbnode_t*)_RB_TREE_ITERATOR_COREPOS(it_iter))->_pby_data, &b_result); assert(b_result); } }
/** * Initialize element auxiliary function */ void _rb_tree_init_elem_auxiliary(_rb_tree_t* pt_rb_tree, _rbnode_t* pt_node) { assert(pt_rb_tree != NULL); assert(pt_node != NULL); assert(_rb_tree_is_inited(pt_rb_tree) || _rb_tree_is_created(pt_rb_tree)); /* initialize new elements */ if(_GET_RB_TREE_TYPE_STYLE(pt_rb_tree) == _TYPE_CSTL_BUILTIN) { /* get element type name */ char s_elemtypename[_TYPE_NAME_SIZE + 1]; _type_get_elem_typename(_GET_RB_TREE_TYPE_NAME(pt_rb_tree), s_elemtypename); _GET_RB_TREE_TYPE_INIT_FUNCTION(pt_rb_tree)(pt_node->_pby_data, s_elemtypename); } else { bool_t b_result = _GET_RB_TREE_TYPE_SIZE(pt_rb_tree); _GET_RB_TREE_TYPE_INIT_FUNCTION(pt_rb_tree)(pt_node->_pby_data, &b_result); assert(b_result); } }
/** * Insert the value into subtree. */ _rbnode_t* _rb_tree_insert_rbnode(_rb_tree_t* pt_rb_tree, const void* cpv_value) { _rbnode_t* pt_parent = NULL; _rbnode_t* pt_cur = NULL; bool_t b_result = false; bool_t b_less = false; assert(pt_rb_tree != NULL); assert(cpv_value != NULL); assert(_rb_tree_is_inited(pt_rb_tree)); /* if the rb tree is empty */ if(_rb_tree_empty(pt_rb_tree)) { /* allocat a new root */ pt_cur = _alloc_allocate( (_alloc_t*)&pt_rb_tree->_t_allocator, _RB_TREE_NODE_SIZE(_GET_RB_TREE_TYPE_SIZE(pt_rb_tree)), 1); assert(pt_cur != NULL); _rb_tree_init_elem_auxiliary(pt_rb_tree, pt_cur); /* set its color is BLACK */ pt_cur->_pt_left = pt_cur->_pt_right = NULL; pt_cur->_t_color = BLACK; pt_cur->_pt_parent = (_rbnode_t*)&pt_rb_tree->_t_rbroot; b_result = _GET_RB_TREE_TYPE_SIZE(pt_rb_tree); _GET_RB_TREE_TYPE_COPY_FUNCTION(pt_rb_tree)(pt_cur->_pby_data, cpv_value, &b_result); assert(b_result); /* insert the node */ pt_rb_tree->_t_rbroot._pt_parent = pt_cur; } else { pt_parent = pt_rb_tree->_t_rbroot._pt_parent; b_less = _GET_RB_TREE_TYPE_SIZE(pt_rb_tree); _rb_tree_elem_compare_auxiliary(pt_rb_tree, cpv_value, pt_parent->_pby_data, &b_less); if(b_less) { pt_cur = pt_parent->_pt_left; } else { pt_cur = pt_parent->_pt_right; } /* from the root to insert position */ while(pt_cur != NULL) { /* next current position */ pt_parent = pt_cur; b_less = _GET_RB_TREE_TYPE_SIZE(pt_rb_tree); _rb_tree_elem_compare_auxiliary(pt_rb_tree, cpv_value, pt_parent->_pby_data, &b_less); if(b_less) { pt_cur = pt_parent->_pt_left; } else { pt_cur = pt_parent->_pt_right; } } /* allocate new node */ pt_cur = _alloc_allocate( (_alloc_t*)&pt_rb_tree->_t_allocator, _RB_TREE_NODE_SIZE(_GET_RB_TREE_TYPE_SIZE(pt_rb_tree)), 1); assert(pt_cur != NULL); _rb_tree_init_elem_auxiliary(pt_rb_tree, pt_cur); pt_cur->_pt_left = pt_cur->_pt_right = NULL; pt_cur->_t_color = RED; pt_cur->_pt_parent = pt_parent; b_result = _GET_RB_TREE_TYPE_SIZE(pt_rb_tree); _GET_RB_TREE_TYPE_COPY_FUNCTION(pt_rb_tree)(pt_cur->_pby_data, cpv_value, &b_result); assert(b_result); if(b_less) { assert(pt_parent->_pt_left == NULL); pt_parent->_pt_left = pt_cur; } else { assert(pt_parent->_pt_right == NULL); pt_parent->_pt_right = pt_cur; } if(_rb_tree_get_color(pt_parent) == RED) { _rb_tree_rebalance(pt_rb_tree, pt_cur); } } return pt_cur; }