/* verify that all API calls are exported */ static void test_api(void) { CRBTree t = {}; CRBNode n = C_RBNODE_INIT(n); assert(!c_rbnode_is_linked(&n)); /* init, is_linked, add, remove, remove_init */ c_rbtree_add(&t, NULL, &t.root, &n); assert(c_rbnode_is_linked(&n)); c_rbtree_remove_init(&t, &n); assert(!c_rbnode_is_linked(&n)); c_rbtree_add(&t, NULL, &t.root, &n); assert(c_rbnode_is_linked(&n)); c_rbtree_remove(&t, &n); assert(c_rbnode_is_linked(&n)); /* @n wasn't touched */ c_rbnode_init(&n); assert(!c_rbnode_is_linked(&n)); /* first, last, leftmost, rightmost, next, prev */ assert(!c_rbtree_first(&t)); assert(!c_rbtree_last(&t)); assert(&n == c_rbnode_leftmost(&n)); assert(&n == c_rbnode_rightmost(&n)); assert(!c_rbnode_next(&n)); assert(!c_rbnode_prev(&n)); }
/** * c_rbnode_prev() - return previous node * @n: current node, or NULL * * An RB-Tree always defines a linear order of its elements. This function * returns the logically previous node to @n. If @n is NULL, the first node or * unlinked, this returns NULL. * * Worst case runtime (n: number of elements in tree): O(log(n)) * * Return: Pointer to previous node, or NULL. */ _c_public_ CRBNode *c_rbnode_prev(CRBNode *n) { CRBNode *p; if (!c_rbnode_is_linked(n)) return NULL; if (n->left) return c_rbnode_rightmost(n->left); while ((p = c_rbnode_parent(n)) && n == p->left) n = p; return p; }
/** * c_rbtree_last() - return last node * @t: tree to operate on * * An RB-Tree always defines a linear order of its elements. This function * returns the logically last node in @t. If @t is empty, NULL is returned. * * Fixed runtime (n: number of elements in tree): O(log(n)) * * Return: Pointer to last node, or NULL. */ _c_public_ CRBNode *c_rbtree_last(CRBTree *t) { c_assert(t); return c_rbnode_rightmost(t->root); }