Commit 3b9cef12 authored by Chris Müller's avatar Chris Müller

lib: add min- and max-heap implementation for priority queues.

parent 321f424a
......@@ -3,6 +3,7 @@ set(SOURCES
structures/single_linked_list.c
structures/double_linked_list.c
structures/red_black_tree.c
structures/heap.c
structures/array.c
structures/structures.c
)
......@@ -15,6 +16,7 @@ set(HEADER
structures/array.h
structures/stack.h
structures/queue.h
structures/heap.h
structures/map.h
structures/list.h
)
......
/*
* Copyright (c) 2012 Christoph Mueller <ruunhb@googlemail.com>
*
* Crystal is free software: you can redistribute it and/or modify
* it under the terms of the Lesser GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Crystal is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Lesser GNU General Public License for more details.
*
* You should have received a copy of the Lesser GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <assert.h>
#include "heap.h"
#include "array.h"
struct CryHeap {
struct CryPtrArray* tree;
cry_ordering_funptr compare;
enum CryHeapOrder order;
};
struct CryHeap*
cry_heap_new(size_t init_capacity, cry_ordering_funptr compare, enum CryHeapOrder order)
{
struct CryHeap* heap = cry_malloc(struct CryHeap);
heap->tree = cry_ptr_array_new(init_capacity);
heap->compare = compare;
heap->order = order;
return heap;
}
void
cry_heap_free(struct CryHeap* heap)
{
assert(heap != 0);
cry_ptr_array_free(heap->tree);
cry_free(heap);
}
void
cry_heap_clear(struct CryHeap* heap, cry_free_funptr fun)
{
assert(heap != 0);
cry_ptr_array_clear(heap->tree, fun);
}
size_t
cry_heap_size(struct CryHeap* heap)
{
assert(heap != 0);
return cry_ptr_array_size(heap->tree);
}
pointer
cry_heap_top(struct CryHeap* heap)
{
assert(heap != 0);
return cry_ptr_array_get(heap->tree, 0);
}
void
cry_heap_push(struct CryHeap* heap, pointer entry)
{
assert(heap != 0);
cry_ptr_array_append(heap->tree, entry);
size_t node_id = cry_ptr_array_size(heap->tree);
while(node_id > 1) {
size_t parent_id = (node_id / 2);
pointer parent = cry_ptr_array_get(heap->tree, parent_id - 1);
if(heap->compare(parent, entry) * heap->order > 0) {
cry_ptr_array_replace(heap->tree, node_id - 1, parent);
cry_ptr_array_replace(heap->tree, parent_id - 1, entry);
node_id = parent_id;
} else {
return;
}
}
}
pointer
cry_heap_pop(struct CryHeap* heap)
{
assert(heap != 0);
if(cry_ptr_array_size(heap->tree) < 2)
return cry_ptr_array_remove(heap->tree, 0);
pointer last = cry_ptr_array_remove(heap->tree, cry_ptr_array_size(heap->tree) - 1);
pointer data = cry_ptr_array_replace(heap->tree, 0, last);
size_t node_id = 1;
while(2 * node_id <= cry_ptr_array_size(heap->tree)) {
pointer right_child = cry_ptr_array_get(heap->tree, 2 * node_id);
pointer left_child = cry_ptr_array_get(heap->tree, 2 * node_id - 1);
pointer child = 0;
size_t child_id = 0;
if(right_child == 0 || heap->compare(left_child, right_child) * heap->order < 0) {
child_id = 2 * node_id;
child = left_child;
} else {
child_id = 2 * node_id + 1;
child = right_child;
}
if(heap->compare(child, last) * heap->order < 0) {
cry_ptr_array_replace(heap->tree, node_id - 1, child);
cry_ptr_array_replace(heap->tree, child_id - 1, last);
node_id = child_id;
} else
return data;
}
return data;
}
/*
* Copyright (c) 2012 Christoph Mueller <ruunhb@googlemail.com>
*
* Crystal is free software: you can redistribute it and/or modify
* it under the terms of the Lesser GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Crystal is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Lesser GNU General Public License for more details.
*
* You should have received a copy of the Lesser GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef CRYSTAL_STRUCTURES_HEAP_H
#define CRYSTAL_STRUCTURES_HEAP_H
#include "structures.h"
struct CryHeap;
enum CryHeapOrder { CRY_MAX = -1, CRY_MIN = 1 };
struct CryHeap* cry_heap_new(size_t init_capacity, cry_ordering_funptr compare, enum CryHeapOrder order);
void cry_heap_free(struct CryHeap* heap);
void cry_heap_clear(struct CryHeap* heap, cry_free_funptr fun);
size_t cry_heap_size(struct CryHeap* heap);
pointer cry_heap_top(struct CryHeap* heap);
void cry_heap_push(struct CryHeap* heap, pointer entry);
pointer cry_heap_pop(struct CryHeap* heap);
#endif // CRYSTAL_STRUCTURES_HEAP_H
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment