Skip to content

Commit f7844d4

Browse files
committed
Heap fixes
1 parent 865b51a commit f7844d4

File tree

3 files changed

+45
-34
lines changed

3 files changed

+45
-34
lines changed

include/heap_t.h

+7-3
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,17 @@
1212

1313
typedef struct {
1414
comparator cmp; // Comparator function
15-
int size; // Max size
16-
int items; // Items currently in heap
15+
int size; // Max size
16+
int items; // Items currently in heap
17+
dtor destructor; // Function to free items
1718
size_t item_size; // Size of item
1819
void** list; // Array of items
1920
} heap_t;
2021

21-
heap_t* heap_create(int size, size_t type_size, comparator cmp);
22+
heap_t* heap_create(int size,
23+
size_t type_size,
24+
comparator cmp,
25+
dtor destructor);
2226
void heap_clear(heap_t* heap);
2327
void heap_destroy(heap_t* heap);
2428
void heap_push(heap_t* heap, void* item);

src/heap_t.c

+34-27
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ void heap_swap(heap_t* heap, int a, int b)
2929
/*
3030
* Create a new fixed size heap.
3131
*/
32-
heap_t* heap_create(int size, size_t type_size, comparator cmp)
32+
heap_t* heap_create(int size, size_t type_size, comparator cmp, dtor destructor)
3333
{
3434
heap_t* h = NULL;
3535

@@ -43,6 +43,7 @@ heap_t* heap_create(int size, size_t type_size, comparator cmp)
4343
h->items = 0;
4444
h->size = size;
4545
h->item_size = type_size;
46+
h->destructor = destructor;
4647
h->list = calloc(1, type_size * size);
4748

4849
check_mem(h->list);
@@ -61,37 +62,43 @@ heap_t* heap_create(int size, size_t type_size, comparator cmp)
6162
/*
6263
* Decallocate every item in the heap.
6364
*/
64-
void heap_clear(heap_t* heap)
65+
void heap_clear(heap_t* h)
6566
{
6667
int i = 0;
67-
if(heap->items > 0) {
68-
for(i = 0; i < heap->size; i++) {
69-
if(heap->list[i] != NULL) {
70-
free(heap->list[i]);
68+
if(h->items <= 0) {
69+
return;
70+
}
71+
for(i = 0; i < h->size; i++) {
72+
if(h->list[i] != NULL) {
73+
if(h->destructor != NULL) {
74+
h->destructor(h->list[i]);
7175
}
76+
h->list[i] = NULL;
7277
}
7378
}
7479
}
7580

7681
/*
7782
* Deallocate a heap
7883
*/
79-
void heap_destroy(heap_t* heap)
84+
void heap_destroy(heap_t* h)
8085
{
81-
if(heap != NULL) {
82-
if(heap->list != NULL) {
83-
free(heap->list);
84-
}
85-
free(heap);
86+
if(h == NULL) {
87+
return;
88+
}
89+
if(h->list != NULL) {
90+
heap_clear(h);
91+
free(h->list);
8692
}
93+
free(h);
8794
}
8895

8996
/*
9097
* Return the index of the items parent
9198
*/
92-
int heap_parent(const heap_t* heap, const int pos) {
99+
int heap_parent(const heap_t* h, const int pos) {
93100
check(pos >= 0, "Heap position must be greater than 0");
94-
check(pos < heap->items, "Heap position is out of range");
101+
check(pos < h->items, "Heap position is out of range");
95102
return (pos - 1) / 2;
96103

97104
error:
@@ -101,15 +108,15 @@ int heap_parent(const heap_t* heap, const int pos) {
101108
/*
102109
* Determine if the element at pos is a leaf node
103110
*/
104-
bool heap_leaf(heap_t* heap, int pos) {
105-
return (pos >= heap->items / 2) && (pos < heap->items);
111+
bool heap_leaf(heap_t* h, int pos) {
112+
return (pos >= h->items / 2) && (pos < h->items);
106113
}
107114

108115
/*
109116
* Get the index of the left child of element at pos
110117
*/
111-
int heap_left(heap_t* heap, int pos) {
112-
check(pos < heap->items, "Heap position is out of range");
118+
int heap_left(heap_t* h, int pos) {
119+
check(pos < h->items, "Heap position is out of range");
113120
return (2 * pos) + 1;
114121

115122
error:
@@ -119,8 +126,8 @@ int heap_left(heap_t* heap, int pos) {
119126
/*
120127
* Get index of the right child of element at pos
121128
*/
122-
int heap_right(heap_t* heap, int pos) {
123-
check(pos < heap->items, "Heap position is out of range");
129+
int heap_right(heap_t* h, int pos) {
130+
check(pos < h->items, "Heap position is out of range");
124131
return (2 * pos) + 2;
125132

126133
error:
@@ -130,21 +137,21 @@ int heap_right(heap_t* heap, int pos) {
130137
/*
131138
* Move element at pos to its correct position within the heap
132139
*/
133-
void heap_sift(heap_t* heap, int pos) {
140+
void heap_sift(heap_t* h, int pos) {
134141
int j;
135-
while(!heap_leaf(heap, pos)) {
136-
j = heap_left(heap, pos);
142+
while(!heap_leaf(h, pos)) {
143+
j = heap_left(h, pos);
137144

138-
if((j < heap->items - 1) &&
139-
(heap->cmp(heap->list[j], heap->list[j+1]) > 0)) {
145+
if((j < h->items - 1) &&
146+
(h->cmp(h->list[j], h->list[j+1]) > 0)) {
140147
j++;
141148
}
142149

143-
if(heap->cmp(heap->list[pos], heap->list[j]) <= 0) {
150+
if(h->cmp(h->list[pos], h->list[j]) <= 0) {
144151
return;
145152
}
146153

147-
heap_swap(heap, pos, j);
154+
heap_swap(h, pos, j);
148155
pos = j;
149156
}
150157
}

tests/heap_t_tests.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,14 @@ int int_cmp_asc(void* a, void* b) {
77
}
88

99
char* test_create() {
10-
heap_t* heap = heap_create(10, sizeof(int), int_cmp_asc);
10+
heap_t* heap = heap_create(10, sizeof(int), int_cmp_asc, NULL);
1111
mu_assert(heap != NULL, "Failed to create heap");
12-
heap_clear(heap);
1312
heap_destroy(heap);
1413
return NULL;
1514
}
1615

1716
char* test_heap_push() {
18-
heap_t* heap = heap_create(10, sizeof(int), int_cmp_asc);
17+
heap_t* heap = heap_create(10, sizeof(int), int_cmp_asc, NULL);
1918
mu_assert(heap != NULL, "Failed to create heap");
2019

2120
heap_push(heap, (void*) 5);
@@ -38,7 +37,7 @@ char* test_heap_push() {
3837
}
3938

4039
char* test_heap_pushpop() {
41-
heap_t* heap = heap_create(10, sizeof(int), int_cmp_asc);
40+
heap_t* heap = heap_create(10, sizeof(int), int_cmp_asc, NULL);
4241
debug("Pushpop 4: %d", (int) heap_pushpop(heap, (void*) 4));
4342
heap_push(heap, (void*) 1);
4443
heap_push(heap, (void*) 2);
@@ -57,6 +56,7 @@ char* test_heap_pushpop() {
5756
n = (int) heap_pop(heap);
5857
mu_assert(n == i, "Incorrect value popped off the heap");
5958
}
59+
heap_destroy(heap);
6060
return NULL;
6161
}
6262

0 commit comments

Comments
 (0)