Skip to content

Commit 8f41f0d

Browse files
committed
min_binary_heap
1 parent e5dad3f commit 8f41f0d

File tree

1 file changed

+267
-0
lines changed

1 file changed

+267
-0
lines changed
Lines changed: 267 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,267 @@
1+
/**
2+
* @file
3+
* @brief Implementation of [Min Binary
4+
* Heap](https://en.wikipedia.org/wiki/Binary_heap)
5+
* @details
6+
* A Min Binary Heap is a complete binary tree-based data structure where the
7+
* value of each node is less than or equal to the values of its children. This
8+
* property ensures that the minimum element is always at the root, allowing
9+
* efficient retrieval and removal of the smallest element.
10+
*
11+
* @author [Aryan Singh](https://github.com/Dibbu-cell)
12+
*/
13+
14+
#include <assert.h> /// for assert
15+
#include <stdbool.h> /// for bool type
16+
#include <stdio.h> /// for IO operations
17+
#include <stdlib.h> /// for malloc, realloc, free
18+
19+
/**
20+
* @brief Structure representing a Min Binary Heap
21+
*/
22+
struct min_binary_heap
23+
{
24+
int *arr; ///< pointer to the heap array
25+
size_t size; ///< current number of elements in the heap
26+
size_t capacity; ///< current capacity of the heap array
27+
};
28+
29+
/**
30+
* @brief Create a new Min Binary Heap with given initial capacity
31+
* @param capacity initial capacity of the heap
32+
* @returns pointer to the created heap, or NULL on failure
33+
*/
34+
struct min_binary_heap *min_heap_create(size_t capacity)
35+
{
36+
struct min_binary_heap *heap =
37+
(struct min_binary_heap *)malloc(sizeof(struct min_binary_heap));
38+
if (!heap)
39+
return NULL;
40+
heap->arr = (int *)malloc(capacity * sizeof(int));
41+
if (!heap->arr)
42+
{
43+
free(heap);
44+
return NULL;
45+
}
46+
heap->size = 0;
47+
heap->capacity = capacity;
48+
return heap;
49+
}
50+
51+
/**
52+
* @brief Free the memory used by the heap
53+
* @param heap pointer to the heap
54+
*/
55+
void min_heap_destroy(struct min_binary_heap *heap)
56+
{
57+
if (heap)
58+
{
59+
free(heap->arr);
60+
free(heap);
61+
}
62+
}
63+
64+
/**
65+
* @brief Swap two integers
66+
* @param a pointer to first integer
67+
* @param b pointer to second integer
68+
*/
69+
static void swap(int *a, int *b)
70+
{
71+
int temp = *a;
72+
*a = *b;
73+
*b = temp;
74+
}
75+
76+
/**
77+
* @brief Heapify up to maintain min-heap property after insertion
78+
* @param heap pointer to the heap
79+
* @param idx index of the newly inserted element
80+
*/
81+
static void heapify_up(struct min_binary_heap *heap, size_t idx)
82+
{
83+
if (idx == 0)
84+
return;
85+
size_t parent = (idx - 1) / 2;
86+
if (heap->arr[parent] > heap->arr[idx])
87+
{
88+
swap(&heap->arr[parent], &heap->arr[idx]);
89+
heapify_up(heap, parent);
90+
}
91+
}
92+
93+
/**
94+
* @brief Heapify down to maintain min-heap property after extraction
95+
* @param heap pointer to the heap
96+
* @param idx index to heapify down from
97+
*/
98+
static void heapify_down(struct min_binary_heap *heap, size_t idx)
99+
{
100+
size_t left = 2 * idx + 1;
101+
size_t right = 2 * idx + 2;
102+
size_t smallest = idx;
103+
104+
if (left < heap->size && heap->arr[left] < heap->arr[smallest])
105+
smallest = left;
106+
if (right < heap->size && heap->arr[right] < heap->arr[smallest])
107+
smallest = right;
108+
109+
if (smallest != idx)
110+
{
111+
swap(&heap->arr[idx], &heap->arr[smallest]);
112+
heapify_down(heap, smallest);
113+
}
114+
}
115+
116+
/**
117+
* @brief Insert a value into the min binary heap
118+
* @param heap pointer to the heap
119+
* @param value value to insert
120+
* @returns true if insertion succeeded, false otherwise
121+
*/
122+
bool min_heap_insert(struct min_binary_heap *heap, int value)
123+
{
124+
if (!heap)
125+
return false;
126+
if (heap->size == heap->capacity)
127+
{
128+
size_t new_capacity = heap->capacity * 2;
129+
int *new_arr = (int *)realloc(heap->arr, new_capacity * sizeof(int));
130+
if (!new_arr)
131+
return false;
132+
heap->arr = new_arr;
133+
heap->capacity = new_capacity;
134+
}
135+
heap->arr[heap->size] = value;
136+
heapify_up(heap, heap->size);
137+
heap->size++;
138+
return true;
139+
}
140+
141+
/**
142+
* @brief Extract the minimum value from the heap
143+
* @param heap pointer to the heap
144+
* @param out pointer to store the extracted value
145+
* @returns true if extraction succeeded, false if heap is empty
146+
*/
147+
bool min_heap_extract_min(struct min_binary_heap *heap, int *out)
148+
{
149+
if (!heap || heap->size == 0)
150+
return false;
151+
if (out)
152+
*out = heap->arr[0];
153+
heap->arr[0] = heap->arr[heap->size - 1];
154+
heap->size--;
155+
heapify_down(heap, 0);
156+
return true;
157+
}
158+
159+
/**
160+
* @brief Get the minimum value from the heap without removing it
161+
* @param heap pointer to the heap
162+
* @param out pointer to store the minimum value
163+
* @returns true if heap is not empty, false otherwise
164+
*/
165+
bool min_heap_peek(const struct min_binary_heap *heap, int *out)
166+
{
167+
if (!heap || heap->size == 0)
168+
return false;
169+
if (out)
170+
*out = heap->arr[0];
171+
return true;
172+
}
173+
174+
/**
175+
* @brief Search for a value in the heap (linear search)
176+
* @param heap pointer to the heap
177+
* @param value value to search for
178+
* @returns true if value is found, false otherwise
179+
*/
180+
bool min_heap_search(const struct min_binary_heap *heap, int value)
181+
{
182+
if (!heap)
183+
return false;
184+
for (size_t i = 0; i < heap->size; ++i)
185+
{
186+
if (heap->arr[i] == value)
187+
return true;
188+
}
189+
return false;
190+
}
191+
192+
/**
193+
* @brief Display the heap elements in array order
194+
* @param heap pointer to the heap
195+
*/
196+
void min_heap_display(const struct min_binary_heap *heap)
197+
{
198+
if (!heap)
199+
return;
200+
printf("Heap elements: ");
201+
for (size_t i = 0; i < heap->size; ++i) printf("%d ", heap->arr[i]);
202+
printf("\n");
203+
}
204+
205+
/**
206+
* @brief Self-test implementations for Min Binary Heap
207+
* @returns void
208+
*/
209+
static void test_min_binary_heap()
210+
{
211+
struct min_binary_heap *heap = min_heap_create(4);
212+
assert(heap != NULL);
213+
214+
// Test insertion
215+
assert(min_heap_insert(heap, 10));
216+
assert(min_heap_insert(heap, 4));
217+
assert(min_heap_insert(heap, 15));
218+
assert(min_heap_insert(heap, 20));
219+
assert(min_heap_insert(heap, 0)); // triggers resize
220+
221+
// Test display (should be in heap order, not sorted)
222+
min_heap_display(heap);
223+
224+
// Test search
225+
assert(min_heap_search(heap, 10) == true);
226+
assert(min_heap_search(heap, 99) == false);
227+
228+
// Test peek
229+
int min_val = -1;
230+
assert(min_heap_peek(heap, &min_val));
231+
assert(min_val == 0);
232+
233+
// Test extract min
234+
int extracted = -1;
235+
assert(min_heap_extract_min(heap, &extracted));
236+
assert(extracted == 0);
237+
238+
assert(min_heap_peek(heap, &min_val));
239+
assert(min_val == 4);
240+
241+
// Extract all and check order
242+
int prev = -1;
243+
while (heap->size > 0)
244+
{
245+
assert(min_heap_extract_min(heap, &extracted));
246+
if (prev != -1)
247+
assert(prev <= extracted); // Should be non-decreasing
248+
prev = extracted;
249+
}
250+
251+
// Heap should be empty now
252+
assert(min_heap_peek(heap, &min_val) == false);
253+
254+
min_heap_destroy(heap);
255+
256+
printf("All Min Binary Heap tests have successfully passed!\n");
257+
}
258+
259+
/**
260+
* @brief Main function
261+
* @returns 0 on exit
262+
*/
263+
int main(void)
264+
{
265+
test_min_binary_heap(); // run self-test implementations
266+
return 0;
267+
}

0 commit comments

Comments
 (0)