static void _gtk_rbtree_test (GtkRBTree *tree) { GtkRBTree *tmp_tree; if (tree == NULL) return; /* Test the entire tree */ tmp_tree = tree; while (tmp_tree->parent_tree) tmp_tree = tmp_tree->parent_tree; if (_gtk_rbtree_is_nil (tmp_tree->root)) return; _gtk_rbtree_test_structure (tmp_tree); g_assert ((_count_nodes (tmp_tree, tmp_tree->root->left) + _count_nodes (tmp_tree, tmp_tree->root->right) + 1) == tmp_tree->root->count); _gtk_rbtree_test_height (tmp_tree, tmp_tree->root); _gtk_rbtree_test_dirty (tmp_tree, tmp_tree->root, GTK_RBNODE_FLAG_SET (tmp_tree->root, GTK_RBNODE_DESCENDANTS_INVALID)); g_assert (count_total (tmp_tree, tmp_tree->root) == tmp_tree->root->total_count); }
void _gtk_rbtree_test (const gchar *where, GtkRBTree *tree) { GtkRBTree *tmp_tree; if (tree == NULL) return; /* Test the entire tree */ tmp_tree = tree; while (tmp_tree->parent_tree) tmp_tree = tmp_tree->parent_tree; g_assert (tmp_tree->nil != NULL); if (tmp_tree->root == tmp_tree->nil) return; _gtk_rbtree_test_structure (tmp_tree); g_assert ((_count_nodes (tmp_tree, tmp_tree->root->left) + _count_nodes (tmp_tree, tmp_tree->root->right) + 1) == tmp_tree->root->count); _gtk_rbtree_test_height (tmp_tree, tmp_tree->root); _gtk_rbtree_test_dirty (tmp_tree, tmp_tree->root, GTK_RBNODE_FLAG_SET (tmp_tree->root, GTK_RBNODE_DESCENDANTS_INVALID)); g_assert (count_parity (tmp_tree, tmp_tree->root) == tmp_tree->root->parity); }
static gint _count_nodes (GtkRBTree *tree, GtkRBNode *node) { gint res; if (_gtk_rbtree_is_nil (node)) return 0; g_assert (node->left); g_assert (node->right); res = (_count_nodes (tree, node->left) + _count_nodes (tree, node->right) + 1); if (res != node->count) g_print ("Tree failed\n"); return res; }
int ptree_replace(void *v, ptree_node_t **rootp, int (*cmp)(const void *v1, const void *v2), void **oldval) { struct ptree_node **parentpp; struct ptree_node *parentp; struct ptree_node *pn; int c; #ifdef VERIFY_TREE int countStart = _count_nodes(rootp), countEnd=0; #endif parentp = *rootp; parentpp = rootp; #ifdef VERIFY_TREE assert(_verify_tree(rootp, cmp)); #endif //if we find v in the tree, replace it if ((c = _walk_to(v, &parentp, &parentpp, cmp)) == 0) { if (oldval) *oldval = parentp->pn_value; parentp->pn_value = v; #ifdef VERIFY_TREE assert(_verify_tree(rootp, cmp)); #endif #ifdef VERIFY_TREE countEnd = _count_nodes(rootp); assert(countEnd == countStart); #endif return 1; } //otherwise, add it to the tree if (!(pn = malloc(sizeof (*pn)))) return 0; memset(pn, 0, sizeof (*pn)); pn->pn_value = v; pn->pn_parent = parentp; *parentpp = pn; if (oldval) *oldval = 0; #ifdef VERIFY_TREE assert(_verify_tree(rootp, cmp)); #endif #ifdef VERIFY_TREE countEnd = _count_nodes(rootp); countStart++; assert(countEnd == countStart); #endif return 1; }
static void _remove_node(ptree_node_t **rootp, ptree_node_t *pn, void **oldval) { ptree_node_t **pp; ptree_node_t **predp; ptree_node_t *pred; #ifdef VERIFY_TREE int countStart = _count_nodes(rootp), countEnd=0; #endif //Find pn in the tree if (!pn->pn_parent) { assert(rootp && pn == *rootp); pp = rootp; } else { if (pn->pn_parent->pn_left == pn) pp = &pn->pn_parent->pn_left; else pp = &pn->pn_parent->pn_right; } //pp should now point at the location where pn is stored in the tree assert(pp); //Best case - only one child, on no children, just remove as in a list if (!pn->pn_left) { *pp = pn->pn_right; if (pn->pn_right) pn->pn_right->pn_parent = pn->pn_parent; } else if (!pn->pn_right) { *pp = pn->pn_left; if (pn->pn_left) pn->pn_left->pn_parent = pn->pn_parent; } //Worst case: pn contains both left and right children else { for (predp = &pn->pn_left; (*predp)->pn_right; ) predp = &(*predp)->pn_right; pred = *predp; //pred either has a left child or no child if (pred->pn_parent->pn_left == pred) pred->pn_parent->pn_left = pred->pn_left; else pred->pn_parent->pn_right = pred->pn_left; if(pred->pn_left) pred->pn_left->pn_parent = pred->pn_parent; *pp = pred; pred->pn_parent = pn->pn_parent; pred->pn_left = pn->pn_left; pred->pn_right = pn->pn_right; if (pn->pn_left) pn->pn_left->pn_parent = pred; pn->pn_right->pn_parent = pred; } //Return the value of the removed node if (oldval) *oldval = pn->pn_value; free(pn); #ifdef VERIFY_TREE countEnd = _count_nodes(rootp); countStart--; assert(countEnd == countStart); #endif }