9#ifndef satoko__utils__heap_h
10#define satoko__utils__heap_h
30static inline unsigned left(
unsigned i) {
return 2 * i + 1; }
31static inline unsigned right(
unsigned i) {
return (i + 1) * 2; }
32static inline unsigned parent(
unsigned i) {
return (i - 1) >> 1; }
34static inline int compare(
heap_t *
p,
unsigned x,
unsigned y)
39static inline void heap_percolate_up(
heap_t *h,
unsigned i)
41 unsigned x = vec_uint_at(h->data, i);
42 unsigned p = parent(i);
44 while (i != 0 && compare(h, x, vec_uint_at(h->data,
p))) {
45 vec_uint_assign(h->data, i, vec_uint_at(h->data,
p));
46 vec_int_assign(h->indices, vec_uint_at(h->data,
p), (
int) i);
50 vec_uint_assign(h->data, i, x);
51 vec_int_assign(h->indices, x, (
int) i);
54static inline void heap_percolate_down(
heap_t *h,
unsigned i)
56 unsigned x = vec_uint_at(h->data, i);
58 while (left(i) < vec_uint_size(h->data)) {
59 unsigned child = right(i) < vec_uint_size(h->data) &&
60 compare(h, vec_uint_at(h->data, right(i)), vec_uint_at(h->data, left(i)))
64 if (!compare(h, vec_uint_at(h->data, child), x))
67 vec_uint_assign(h->data, i, vec_uint_at(h->data, child));
68 vec_int_assign(h->indices, vec_uint_at(h->data, i), (
int) i);
71 vec_uint_assign(h->data, i, x);
72 vec_int_assign(h->indices, x, (
int) i);
82 p->indices = vec_int_alloc(0);
83 p->data = vec_uint_alloc(0);
87static inline void heap_free(
heap_t *
p)
89 vec_int_free(
p->indices);
90 vec_uint_free(
p->data);
94static inline unsigned heap_size(
heap_t *
p)
96 return vec_uint_size(
p->data);
99static inline int heap_in_heap(
heap_t *
p,
unsigned entry)
101 return (entry < vec_int_size(
p->indices)) &&
102 (vec_int_at(
p->indices, entry) >= 0);
105static inline void heap_increase(
heap_t *
p,
unsigned entry)
107 assert(heap_in_heap(
p, entry));
108 heap_percolate_down(
p, (
unsigned) vec_int_at(
p->indices, entry));
111static inline void heap_decrease(
heap_t *
p,
unsigned entry)
113 assert(heap_in_heap(
p, entry));
114 heap_percolate_up(
p, (
unsigned) vec_int_at(
p->indices, entry));
117static inline void heap_insert(
heap_t *
p,
unsigned entry)
119 if (vec_int_size(
p->indices) < entry + 1) {
120 unsigned old_size = vec_int_size(
p->indices);
123 vec_int_resize(
p->indices, entry + 1);
125 vec_int_assign(
p->indices, i, -1);
127 assert(!heap_in_heap(
p, entry));
128 vec_int_assign(
p->indices, entry, (
int) vec_uint_size(
p->data));
129 vec_uint_push_back(
p->data, entry);
130 heap_percolate_up(
p, (
unsigned) vec_int_at(
p->indices, entry));
133static inline void heap_update(
heap_t *
p,
unsigned i)
135 if (!heap_in_heap(
p, i))
138 heap_percolate_up(
p, (
unsigned) vec_int_at(
p->indices, i));
139 heap_percolate_down(
p, (
unsigned) vec_int_at(
p->indices, i));
149 vec_int_assign(
p->indices, entry, -1);
150 vec_uint_clear(
p->data);
152 vec_int_assign(
p->indices, entry, (
int) j);
153 vec_uint_push_back(
p->data, entry);
155 for ((i = vec_uint_size(
p->data) / 2 - 1); i >= 0; i--)
156 heap_percolate_down(
p, (
unsigned) i);
159static inline void heap_clear(
heap_t *
p)
161 vec_int_clear(
p->indices);
162 vec_uint_clear(
p->data);
165static inline unsigned heap_remove_min(
heap_t *
p)
167 unsigned x = vec_uint_at(
p->data, 0);
168 vec_uint_assign(
p->data, 0, vec_uint_at(
p->data, vec_uint_size(
p->data) - 1));
169 vec_int_assign(
p->indices, vec_uint_at(
p->data, 0), 0);
170 vec_int_assign(
p->indices, x, -1);
171 vec_uint_pop_back(
p->data);
172 if (vec_uint_size(
p->data) > 1)
173 heap_percolate_down(
p, 0);
#define ABC_NAMESPACE_HEADER_END
#define ABC_NAMESPACE_HEADER_START
NAMESPACES ///.
#define satoko_alloc(type, n_elements)
typedefABC_NAMESPACE_HEADER_START struct heap_t_ heap_t
#define vec_act_at(vec, idx)
typedefABC_NAMESPACE_HEADER_START struct vec_int_t_ vec_int_t
#define vec_int_foreach_start(vec, entry, i, start)
#define vec_uint_foreach(vec, entry, i)
typedefABC_NAMESPACE_HEADER_START struct vec_uint_t_ vec_uint_t