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)
|
void heap_remove(heap_node_t *node)
|
||||||
{
|
{
|
||||||
heap_t *heap = node->heap;
|
heap_t *heap = node->heap;
|
||||||
|
14
test/heap.c
14
test/heap.c
@ -30,7 +30,12 @@
|
|||||||
#include <threadless/heap.h>
|
#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]);
|
const size_t data_count = sizeof(data) / sizeof(data[0]);
|
||||||
|
|
||||||
|
|
||||||
@ -58,7 +63,7 @@ static int run(allocator_t *allocator)
|
|||||||
heap_node_t *node;
|
heap_node_t *node;
|
||||||
|
|
||||||
allocation_init(&alloc, allocator);
|
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) {
|
if (error) {
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
@ -74,9 +79,14 @@ static int run(allocator_t *allocator)
|
|||||||
|
|
||||||
/* remove from middle */
|
/* remove from middle */
|
||||||
heap_remove(&(values[0].node));
|
heap_remove(&(values[0].node));
|
||||||
|
|
||||||
/* remove from end */
|
/* remove from end */
|
||||||
heap_remove(&(values[data_count - 1].node));
|
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) */
|
/* pull values out of heap (minimum first) */
|
||||||
while (NULL != (node = heap_pop(&heap))) {
|
while (NULL != (node = heap_pop(&heap))) {
|
||||||
value_t *value = container_of(node, value_t, node);
|
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);
|
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
|
/** Remove an arbitrary @p node from its heap
|
||||||
* @param[in,out] node node
|
* @param[in,out] node node
|
||||||
* @pre @p node must be in a heap
|
* @pre @p node must be in a heap
|
||||||
|
Loading…
x
Reference in New Issue
Block a user