mirror of
https://github.com/jrcutler/threadless.io.git
synced 2024-07-07 10:35:49 +00:00
Add heap_replace() functionality
This commit is contained in:
parent
ecf9cc606c
commit
aca3db2b06
21
src/heap.c
21
src/heap.c
@ -84,6 +84,27 @@ int heap_push(heap_t *heap, heap_node_t *node)
|
||||
}
|
||||
|
||||
|
||||
void heap_replace(heap_node_t *old, heap_node_t *node)
|
||||
{
|
||||
heap_t *heap = old->heap;
|
||||
size_t pos = old->index;
|
||||
heap_node_t **storage = heap->allocation.memory;
|
||||
|
||||
/* disassociate old node from heap */
|
||||
old->heap = NULL;
|
||||
old->index = 0;
|
||||
|
||||
/* place new node in heap */
|
||||
node->heap = heap;
|
||||
node->index = pos;
|
||||
storage[pos] = node;
|
||||
|
||||
/* restore heap invariant */
|
||||
sift_up(heap, pos, heap->count);
|
||||
sift_down(heap, 0, pos);
|
||||
}
|
||||
|
||||
|
||||
void heap_remove(heap_node_t *node)
|
||||
{
|
||||
heap_t *heap = node->heap;
|
||||
|
14
test/heap.c
14
test/heap.c
@ -30,7 +30,12 @@
|
||||
#include <threadless/heap.h>
|
||||
|
||||
|
||||
const int data[] = { 4 /* duplicate */, 1, 9, 2, 8, 4, 0, 5, 3, 6, 7, 99 };
|
||||
const int data[] = {
|
||||
4 /* duplicate (remove) */,
|
||||
6 /* duplicate (replace with 1) */,
|
||||
9, 2, 8, 4, 0, 5, 3, 6, 7,
|
||||
99 /* remove */,
|
||||
};
|
||||
const size_t data_count = sizeof(data) / sizeof(data[0]);
|
||||
|
||||
|
||||
@ -58,7 +63,7 @@ static int run(allocator_t *allocator)
|
||||
heap_node_t *node;
|
||||
|
||||
allocation_init(&alloc, allocator);
|
||||
error = allocation_realloc_array(&alloc, data_count, sizeof(*values));
|
||||
error = allocation_realloc_array(&alloc, data_count + 1, sizeof(*values));
|
||||
if (error) {
|
||||
return error;
|
||||
}
|
||||
@ -74,9 +79,14 @@ static int run(allocator_t *allocator)
|
||||
|
||||
/* remove from middle */
|
||||
heap_remove(&(values[0].node));
|
||||
|
||||
/* remove from end */
|
||||
heap_remove(&(values[data_count - 1].node));
|
||||
|
||||
/* replace */
|
||||
values[data_count].value = 1;
|
||||
heap_replace(&(values[1].node), &(values[data_count].node));
|
||||
|
||||
/* pull values out of heap (minimum first) */
|
||||
while (NULL != (node = heap_pop(&heap))) {
|
||||
value_t *value = container_of(node, value_t, node);
|
||||
|
@ -84,6 +84,15 @@ static inline heap_node_t *heap_peek(const heap_t *heap)
|
||||
*/
|
||||
int heap_push(heap_t *heap, heap_node_t *node);
|
||||
|
||||
/** Replace an existing @p old node in a heap with a new @p node
|
||||
* @param[in,out] old old node
|
||||
* @param[in,out] node new node
|
||||
* @pre @p old must be in a heap
|
||||
* @post @p old is no longer in a heap
|
||||
* @post @p node is in the heap that previously contained @p old
|
||||
*/
|
||||
void heap_replace(heap_node_t *old, heap_node_t *node);
|
||||
|
||||
/** Remove an arbitrary @p node from its heap
|
||||
* @param[in,out] node node
|
||||
* @pre @p node must be in a heap
|
||||
|
Loading…
x
Reference in New Issue
Block a user