aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMosder <xmosder12@gmail.com>2026-07-10 20:25:56 +0200
committerMosder <xmosder12@gmail.com>2026-07-10 20:25:56 +0200
commit4422f92de05948187eeb0b0067dd947e673f8f1d (patch)
tree15b24dc0409724cc6f9cc8e20bb000ba6f3b9cc2
parentdf37df639f0c28e7cb155172576e7a14cdca8ed6 (diff)
feat: implemented a heap structure
-rw-r--r--analyzer/utils/structures/hashmap.c1
-rw-r--r--analyzer/utils/structures/hashmap.h2
-rw-r--r--analyzer/utils/structures/heap.c109
-rw-r--r--analyzer/utils/structures/heap.h55
4 files changed, 165 insertions, 2 deletions
diff --git a/analyzer/utils/structures/hashmap.c b/analyzer/utils/structures/hashmap.c
index bab6572..5c7fdf9 100644
--- a/analyzer/utils/structures/hashmap.c
+++ b/analyzer/utils/structures/hashmap.c
@@ -1,6 +1,5 @@
#include "hashmap.h"
-#include <stdint.h>
#include <stdlib.h>
#include <string.h>
diff --git a/analyzer/utils/structures/hashmap.h b/analyzer/utils/structures/hashmap.h
index c0ecbe1..4f8e24a 100644
--- a/analyzer/utils/structures/hashmap.h
+++ b/analyzer/utils/structures/hashmap.h
@@ -3,7 +3,7 @@
#include <stddef.h>
-#define HASHMAP_TABLE_SIZE 1024
+#define HASHMAP_TABLE_SIZE 128
typedef struct HashMapNode {
void *key;
diff --git a/analyzer/utils/structures/heap.c b/analyzer/utils/structures/heap.c
new file mode 100644
index 0000000..5310299
--- /dev/null
+++ b/analyzer/utils/structures/heap.c
@@ -0,0 +1,109 @@
+#include "heap.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+Heap *heap_new(size_t element_size, int (*compare)(void *element1, void *element2), void (*element_cleanup)(void *element)) {
+ Heap *heap = malloc(sizeof(Heap));
+ heap->data = malloc(INIT_HEAP_CAPACITY * sizeof(void *));
+ heap->n_elements = 0;
+ heap->element_size = element_size;
+ heap->capacity = INIT_HEAP_CAPACITY;
+ heap->compare = compare;
+ heap->element_cleanup = element_cleanup;
+ return heap;
+}
+
+// return index of parent in heap
+size_t parent(size_t i) {
+ return (i - 1) / 2;
+}
+
+// return index of left child in heap
+size_t left(size_t i) {
+ return 2 * i + 1;
+}
+
+// return index of right child in heap
+size_t right(size_t i) {
+ return 2 * i + 2;
+}
+
+// swap two elements
+void swap(void **p_el1, void **p_el2) {
+ void *tmp = *p_el1;
+ *p_el1 = *p_el2;
+ *p_el2 = tmp;
+}
+
+// expand heap exponentially to fit el_count elements
+void expand_heap(Heap *heap, size_t el_count) {
+ while (heap->capacity < el_count)
+ heap->capacity = (heap->capacity << 1) | 1;
+ heap->data = realloc(heap->data, heap->capacity * sizeof(void *));
+}
+
+void heap_insert(Heap *heap, void *element) {
+ // expand heap if capacity is too small
+ if (heap->n_elements >= heap->capacity)
+ expand_heap(heap, heap->n_elements + 1);
+
+ // insert into the last position
+ size_t i = heap->n_elements;
+ heap->data[i] = malloc(heap->element_size);
+ memcpy(heap->data[i], element, heap->element_size);
+ heap->n_elements++;
+
+ // heapify up
+ while (i > 0 && heap->compare(heap->data[i], heap->data[parent(i)])) {
+ swap(&heap->data[i], &heap->data[parent(i)]);
+ i = parent(i);
+ }
+}
+
+void *heap_top_get(Heap *heap) {
+ return heap->n_elements <= 0 ? NULL : heap->data[0];
+}
+
+void free_heap_element(Heap *heap, size_t index) {
+ if (heap->element_cleanup)
+ heap->element_cleanup(heap->data[index]);
+ free(heap->data[index]);
+}
+
+void heap_top_remove(Heap *heap) {
+ if (heap->n_elements <= 0)
+ return;
+
+ free_heap_element(heap, 0);
+
+ // move last element to root
+ heap->data[0] = heap->data[--heap->n_elements];
+
+ // heapify down
+ size_t i = 0;
+ int changed;
+ do {
+ size_t l = left(i);
+ size_t r = right(i);
+ size_t to_be_parent = i;
+
+ if (l < heap->n_elements && heap->compare(heap->data[l], heap->data[to_be_parent]))
+ to_be_parent = l;
+ if (r < heap->n_elements && heap->compare(heap->data[r], heap->data[to_be_parent]))
+ to_be_parent = r;
+
+ if ((changed = to_be_parent != i)) {
+ swap(&heap->data[to_be_parent], &heap->data[i]);
+ i = to_be_parent;
+ }
+ } while (changed);
+}
+
+void heap_free(Heap *heap) {
+ for (size_t i = 0; i < heap->n_elements; i++) {
+ free_heap_element(heap, i);
+ }
+ free(heap->data);
+ free(heap);
+}
diff --git a/analyzer/utils/structures/heap.h b/analyzer/utils/structures/heap.h
new file mode 100644
index 0000000..e960fb7
--- /dev/null
+++ b/analyzer/utils/structures/heap.h
@@ -0,0 +1,55 @@
+// utils/structures/heap.h
+// a simple implementation of heap
+
+#include <stddef.h>
+
+#define INIT_HEAP_DEPTH 7
+#define INIT_HEAP_CAPACITY (1 << INIT_HEAP_DEPTH) - 1
+
+typedef struct {
+ void **data;
+ size_t n_elements;
+ size_t element_size;
+ size_t capacity;
+ int (*compare)(void *element1, void *element2);
+ void (*element_cleanup)(void *element);
+} Heap;
+
+// create a new heap
+// params:
+// - element_size - size of the heap element
+// - compare - function for comparing elements
+// params:
+// - element1 - pointer to the first of the elements to compare
+// - element2 - pointer to the second of the elements to compare
+// returns:
+// truthy if element1 should be element2's parent (e.g. element1 > element2 for max heap), falsy otherwise
+// - element_cleanup - function for cleaning up any internal allocations inside element (not the element itself)
+// if it has no heap allocations, this should be NULL
+// params:
+// - element - pointer to the element to cleanup
+// returns:
+// pointer to the new heap
+extern Heap *heap_new(size_t element_size, int (*compare)(void *element1, void *element2), void (*element_cleanup)(void *element));
+
+// insert new element into the heap
+// params:
+// - heap - heap to insert to
+// - element - pointer to the element to insert
+extern void heap_insert(Heap *heap, void *element);
+
+// get the top element from the heap
+// params:
+// - heap - heap to get the top element from
+// returns:
+// pointer to the top element in the heap or NULL if heap is empty
+extern void *heap_top_get(Heap *heap);
+
+// remove the top element from the heap
+// params:
+// - heap - heap to remove the top element from
+extern void heap_top_remove(Heap *heap);
+
+// free the heap
+// - heap - heap to free
+extern void heap_free(Heap *heap);