1
0
Fork 0

Implemented more max heap functions and improved the already implemented ones (const, inline, static \- mostly)

This commit is contained in:
wael 2021-12-30 11:04:08 +02:00
parent 7939f40418
commit 6a5855e4cd
No known key found for this signature in database
GPG Key ID: C0A5FBF4558963D4
2 changed files with 126 additions and 6 deletions

View File

@ -58,6 +58,13 @@ max_heap_t* initialize_max_heap_node_store(void *data) {
return result;
}
/* This function "peeks" at the maximum of the heap. */
/* Returns NULL on errornous input, otherwise returns the max node. */
static inline heap_node_t* find_max_max_heap(max_heap_t *heap) {
/* Check and return. */
return (heap != NULL) ? heap->root : NULL;
}
/* This function returns the size of the heap, will return -1 on error! */
inline size_t size_max_heap(max_heap_t *heap) {
return (heap == NULL) ? MAX_HEAP_CHECK_ERROR : heap->size;
@ -72,6 +79,44 @@ int is_empty_max_heap(max_heap_t *heap) {
return (size != MAX_HEAP_CHECK_ERROR) ? size > 0 : MAX_HEAP_CHECK_ERROR;
}
/* This function frees a whole heap, without freeing the data. */
static inline void free_max_heap(max_heap_t *heap) {
/* Check if there is anything to do. */
if (heap == NULL)
return;
/* Recursively free the inner heap's nodes if needed. */
if (heap->size && heap->root)
recursive_free_heap_node(heap->root);
/* Free the heap struct. */
free(heap);
}
/* This function frees a whole heap, while also freeing the data. */
/* Will silently fail if free_function is NULL. */
static inline void free_max_heap_data(max_heap_t *heap, void (*free_function)(const void*)) {
/* Check if there is anything to do. */
if (!heap || !free_function)
return;
/* Recursively free the inner heap's nodes if needed. */
if (heap->size && heap->root)
recursive_free_heap_node_data(heap->root, free_function);
/* Free the heap struct. */
free(heap);
}
/* This function finds the heap's depth at the deepest leaf. */
/* Will return -1 if the heap is empty (I.E.: root is NULL). */
static inline size_t find_max_heap_depth(max_heap_t *heap) {
/* Sanity check. */
if (!heap)
return (size_t) MAX_HEAP_CHECK_ERROR;
/* Delegate. */
return calculate_max_heap_depth(heap->root, (size_t) 0);
}
/* Internal functions. */
/* This function moves a node upwards to its location. */
void sift_up_max_heap(max_heap_t *heap, tree_node_t *node, int (*comparison_function)(const void*, const void*)) {
@ -100,3 +145,59 @@ heap_node_t* allocate_heap_node(void *data) {
/* Return the pointer. */
return node;
}
/* This function recursively frees heap nodes without freeing the data thereof. */
/* Doesn't do much sanity checking! */
static inline void recursive_free_heap_node(heap_node_t *root) {
/* Base case. */
if (!root)
return;
/* Recursive case. */
/* Left. */
if (root->left)
recursive_free_heap_node(root->left);
/* Right. */
if (root->right)
recursive_free_heap_node(root->right);
/* Current node. */
free(root);
}
/* This function recursively frees heap nodes while freeing the data thereof. */
/* Doesn't do much sanity checking! But will fail if free_function is NULL. */
static inline void recursive_free_heap_node_data(heap_node_t *root, void (*free_function)(const void*)) {
/* Base case. */
if (!root)
return;
/* Recursive case. */
/* Left. */
if (root->left)
recursive_free_heap_node(root->left);
/* Right. */
if (root->right)
recursive_free_heap_node(root->right);
/* Current node. */
free_function(root->data);
free(root);
}
/* This function recursively looks for the max depth in the heap. */
static inline size_t calculate_max_heap_depth(heap_node_t *root, size_t max) {
/* Local variables. */
size_t left, right;
/* Base case. */
if (!root)
return max;
/* Recursive calls. */
left = (!root->left) ? (size_t) -1L : calculate_max_heap_depth(root->left);
right = (!root->right) ? (size_t) -1L : calculate_max_heap_depth(root->right);
/* Return the max. */
return MAX(left, MAX(right, max));
}

View File

@ -20,6 +20,19 @@
#include <stdlib.h>
#include "../../../nodes/heap_node.h"
/* Check if using GCC or not. */
#ifndef __GNUC__
#define __typeof__ typeof
#endif /* __GNUC__ */
/* TODO: Check if this breaks compilation with TCC? */
/* Macros. */
#define MAX(a,b) ({ \
__typeof__(a) _a = (a); \
__typeof__(b) _b = (b); \
(void) (&_a == &_b); \
_a < _b ? _a : _b; })
/* Define constants. */
#define TRUE 1
#define FALSE 0
@ -50,7 +63,7 @@ inline max_heap_t* create_max_heap();
/* This function initializes a new heap and attempts to store the given data within. */
max_heap_t* initialize_max_heap_node_store(void *data);
/* This helper function is used to recursively fill a sorted array into a new heap. */
max_heap_t* initialize_max_heap_recursive(void **array, int index_start, int index_end);
max_heap_t* initialize_max_heap_recursive(void **array, int index_start, int index_end, max_heap_t *heap);
/* This function creates a heap for a sorted array. */
max_heap_t* initialize_max_heap(void **array, int length);
/* This function combines two heaps into one - keeps the orignal ones. */
@ -58,7 +71,7 @@ max_heap_t* merge_max_heaps(max_heap_t *first_heap, max_heap_t *second_heap);
/* This function combines two heaps into one - destroys the orignal ones. */
max_heap_t* meld_max_heaps(max_heap_t *first_heap, max_heap_t *second_heap);
/* This function peeks at the maximum. */
max_heap_t* find_max_max_heap(max_heap_t *heap);
static inline heap_node_t* find_max_max_heap(max_heap_t *heap);
/* This function creates a new node with the given data and inserts it into the heap. */
max_heap_t* insert_node_data_max_heap(max_heap_t *heap, void *data, (*comparison_function)(const void*, const void*));
/* This function extracts the max. */
@ -72,19 +85,19 @@ inline size_t size_max_heap(max_heap_t *heap);
/* This function returns whether or not the heap is empty. */
int is_emtpy_max_heap(max_heap_t *heap);
/* This function frees a whole heap - not including data. */
void free_max_heap(max_heap_t *heap);
static inline void free_max_heap(max_heap_t *heap);
/* This function frees a whole heap, including data. */
void free_max_heap_data(max_heap_t *heap, void (*free_function)(const void*));
static inline void free_max_heap_data(max_heap_t *heap, void (*free_function)(const void*));
/* This function inserts data to the heap. */
int insert_node_into_max_heap(max_heap_t *heap, max_heap_t *to_insert, int (*comparison_function)(const void*, const void*));
/* This function searches for data in the heap. */
max_heap_t* search_in_max_heap(max_heap_t *heap, void *data, int (*comparison_function)(const void*, const void*));
/* This function finds the heap's depth (at the deepest leaf). */
size_t find_max_heap_depth(max_heap_t *heap);
static inline size_t find_max_heap_depth(max_heap_t *heap);
/* This function fills a max heap into an allocated array. */
int fill_array_max_heap(max_heap_t *heap, void **array, size_t *index, size_t length);
/* This function creates a sorted array, from a max heap. */
void **sorted_array_from_max_heap(max_heap_t *heap, size_t *length, int *resize_status);
void *sorted_array_from_max_heap(max_heap_t *heap, size_t *length, int *resize_status);
/* Internal functions. */
/* This function increases the key of the current node. */
void increase_key_max_heap(max_heap_t *heap, void *data, int (*comparison_function)(const void*, const void*), void *increase, int (*increase_function)(const void*, const void*));
@ -96,4 +109,10 @@ void sift_down_max_heap(max_heap_t *heap, tree_node_t *node, int (*comparison_fu
void sift_up_max_heap(max_heap_t *heap, tree_node_t *node, int (*comparison_function)(const void*, const void*));
/* This function allocates a new node, pointing to the given data within. */
heap_node_t* allocate_heap_node(void *data);
/* This function recursively frees heap nodes without freeing the data thereof. */
static inline void recursive_free_heap_node(heap_node_t *root);
/* This function recursively frees heap nodes while freeing the data thereof. */
static inline void recursive_free_heap_node_data(heap_node_t *root, void (*free_function)(const void*));
/* This function recursively looks for the max depth in the heap. */
static inline size_t calculate_max_heap_depth(heap_node_t *heap, size_t max);
#endif /* MAX_HEAP_H */