34 struct cstl_heap *
const h,
const unsigned int id)
38 const unsigned int loc =
id + 1;
41 for (b = (1 <<
cstl_fls(loc)) >> 1; p != NULL && b != 0; b >>= 1) {
57static void cstl_heap_promote_child(
struct cstl_heap *
const h,
70 }
else if (p->p->l == p) {
129 if (h->bt.root == NULL) {
140 n->p = cstl_heap_find(h, (h->bt.size - 1) / 2);
146 if (h->bt.size % 2 == 0) {
157 && __cstl_bintree_cmp(&h->bt, n, n->p) > 0) {
158 cstl_heap_promote_child(h, n);
167 if (h->bt.root != NULL) {
168 return (
void *)((uintptr_t)h->bt.root - h->bt.off);
185 n = cstl_heap_find(h, h->bt.size - 1);
186 assert(n->l == NULL && n->r == NULL);
194 }
else if (n->p->l == n) {
202 if (h->bt.root != NULL) {
225 cstl_heap_promote_child(h, c);
230 && __cstl_bintree_cmp(&h->bt, n->l, c) > 0) {
234 && __cstl_bintree_cmp(&h->bt, n->r, c) > 0) {
256static int cmp_integer(
const void *
const a,
const void *
const b,
260 return ((
struct integer *)a)->v - ((
struct integer *)b)->v;
263static int __cstl_heap_verify(
const void *
const elem,
271 &((
const struct integer *)elem)->hn;
273 if (hn->bn.l != NULL) {
275 __cstl_bintree_cmp(&h->bt, hn->bn.l, &hn->bn),
278 if (hn->bn.r != NULL) {
280 __cstl_bintree_cmp(&h->bt, hn->bn.r, &hn->bn),
288static void cstl_heap_verify(
const struct cstl_heap *
const h)
290 if (h->bt.root != NULL) {
294 __cstl_heap_verify, (
void *)h,
304 ck_assert_uint_le(max - min, 1);
309static void __test__cstl_heap_fill(
struct cstl_heap *
const h,
const size_t n)
313 for (i = 0; i < n; i++) {
314 struct integer *
const in = malloc(
sizeof(*in));
323static void __test__cstl_heap_drain(
struct cstl_heap *
const h)
332 ck_assert_int_le(in->v, n);
340 ck_assert_ptr_null(h->bt.root);
347 static const size_t n = 100;
351 __test__cstl_heap_fill(&h, n);
352 cstl_heap_verify(&h);
353 __test__cstl_heap_drain(&h);
357Suite * heap_suite(
void)
359 Suite *
const s = suite_create(
"heap");
363 tc = tcase_create(
"heap");
364 tcase_add_test(tc, fill);
365 suite_add_tcase(s, tc);
static void cstl_swap(void *const x, void *const y, void *const t, const size_t sz)
Swap values at two memory locations via use of a third.
int cstl_fls(unsigned long)
Find the last (highest order) bit set.
cstl_bintree_visit_order_t
Enumeration indicating the order in which a tree element is being visited during cstl_bintree_foreach...
void cstl_bintree_height(const struct cstl_bintree *bt, size_t *min, size_t *max)
Determine the maximum and minimum heights of a tree.
int cstl_bintree_foreach(const struct cstl_bintree *bt, cstl_bintree_const_visit_func_t *visit, void *priv, cstl_bintree_foreach_dir_t dir)
Visit each element in a tree, calling a user-defined function for each visit.
@ CSTL_BINTREE_VISIT_ORDER_LEAF
The only visit to an element that has no children.
@ CSTL_BINTREE_VISIT_ORDER_MID
The second visit to an element, after its first child has/would have been visited.
@ CSTL_BINTREE_FOREACH_DIR_FWD
Each element in the tree is visited from left-to-right.
void * cstl_heap_pop(struct cstl_heap *const h)
Remove the highest valued element from the heap.
const void * cstl_heap_get(const struct cstl_heap *const h)
Get a pointer to the object at the top of the heap.
void cstl_heap_push(struct cstl_heap *const h, void *const p)
Insert a new object into the heap.
static size_t cstl_heap_size(const struct cstl_heap *const h)
Get the number of objects in the heap.
#define DECLARE_CSTL_HEAP(NAME, TYPE, MEMB, CMP, PRIV)
(Statically) declare and initialize a heap
Node to anchor an element within a binary tree.
Node to anchor an element within a heap.