-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmin_heap.c
78 lines (63 loc) · 1.77 KB
/
min_heap.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include "common.h"
#include "min_heap.h"
static size_t parent(size_t i) { return (i - 1)/2; }
static size_t left_child(size_t i) { return 2*i + 1; }
static size_t right_child(size_t i) { return 2*i + 2; }
void min_heap_init(Min_heap *heap)
{
heap->len = 0;
}
void min_heap_free(UNUSED Min_heap *heap) {}
size_t min_heap_len(Min_heap *heap)
{
return heap->len;
}
void min_heap_add(Min_heap *heap, int val)
{
size_t i;
assert(heap->len < HEAP_MAX_SIZE);
for (i = heap->len;
i != 0 && val < heap->storage[parent(i)];
i = parent(i))
heap->storage[i] = heap->storage[parent(i)];
heap->storage[i] = val;
++heap->len;
}
int min_heap_remove(Min_heap *heap)
{
size_t i;
int res = heap->storage[0];
int val = heap->storage[--heap->len];
// Makes it safe to only check whether the left child is out of bounds. A
// non-existent right child will never be selected as min_i.
heap->storage[heap->len] = INT_MAX;
i = 0;
for (;;) {
size_t min_i;
if (left_child(i) >= heap->len)
break;
min_i =
(heap->storage[left_child(i)] < heap->storage[right_child(i)]) ?
left_child(i) : right_child(i);
if (val <= heap->storage[min_i])
break;
heap->storage[i] = heap->storage[min_i];
i = min_i;
}
heap->storage[i] = val;
return res;
}
static bool valid_min_heap_rec(Min_heap *heap, size_t i)
{
bool left_valid;
if (left_child(i) >= heap->len)
return true;
left_valid = valid_min_heap_rec(heap, left_child(i));
if (right_child(i) >= heap->len)
return left_valid;
return left_valid && valid_min_heap_rec(heap, right_child(i));
}
bool valid_min_heap(Min_heap *heap)
{
return valid_min_heap_rec(heap, 0);
}