55 lines
1.2 KiB
C
55 lines
1.2 KiB
C
#include "heap.h"
|
|
|
|
// TODO: remove the extra checks for heap_size if i don't need them based on calling
|
|
static int parent(int i) {
|
|
return (i > 0) ? (i - 1) / 2 : -1;
|
|
}
|
|
|
|
static int left_child(int i) {
|
|
return i * 2 + 1;
|
|
}
|
|
|
|
static int right_child(int i) {
|
|
return i * 2 + 2;
|
|
}
|
|
|
|
static int left_sibling(int i) {
|
|
return (i % 2 == 0) ? i - 1 : -1;
|
|
}
|
|
|
|
static int right_sibling(int i) {
|
|
return (i % 2 == 1) ? i + 1 : -1;
|
|
}
|
|
|
|
void dlos_node_swap(dlos_ComparableNode *arr, int a, int b) {
|
|
dlos_ComparableNode temp = arr[a];
|
|
arr[a] = arr[b];
|
|
arr[b] = temp;
|
|
}
|
|
|
|
static int index_of_larger_child(int i, dlos_Heap *h) {
|
|
int larger = left_child(i);
|
|
if (larger >= h->size) {
|
|
return -1;
|
|
}
|
|
if (larger + 1 < h->size && h->compare(&h->arr[larger], &h->arr[larger + 1]) > 0) {
|
|
larger = larger + 1;
|
|
}
|
|
return larger;
|
|
}
|
|
|
|
void dlos_sift_down(int i, dlos_Heap *h) {
|
|
int target = index_of_larger_child(i, h);
|
|
while (target > 0 && h->compare(&h->arr[i], &h->arr[target]) > 0) {
|
|
dlos_node_swap(h->arr, i, target);
|
|
i = target;
|
|
target = index_of_larger_child(i, h);
|
|
}
|
|
}
|
|
|
|
void dlos_max_heap(dlos_Heap *h) {
|
|
for (int i = parent(h->size - 1); i >= 0; i--) {
|
|
dlos_sift_down(i, h);
|
|
}
|
|
}
|