Implemented more max heap functions and improved the already implemented ones (const, inline, static \- mostly)
This commit is contained in:
parent
7939f40418
commit
6a5855e4cd
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue