void heap_add(heap_t* heap, void* element) { void* tmp; if(heap->top != NULL) { tmp = realloc(heap->top, heap->element_size * (heap->n_elements + 1)); if(tmp == NULL) { printf("Cannot resize heap.\n"); return; } heap->top = tmp; memcpy(heap->top + heap->element_size * heap->n_elements, element, heap->element_size); heap->n_elements++; heap_bubble_up(heap, heap->n_elements - 1); } else { heap->top = malloc(heap->element_size); if(heap->top == NULL) { printf("Cannot allocate heap storage.\n"); return; } memcpy(heap->top, element, heap->element_size); heap->n_elements++; } }
void heap_bubble_up(Heap* heap, int index) { if(index == 0) { return; } int compare = heap->comparator(heap_get(heap, index), heap_parent(heap, index)); if(compare <= 0) { heap_swap(heap, index, heap_parent_index(index)); heap_bubble_up(heap, heap_parent_index(index)); } }
void heap_insert(Heap* heap, void* value) { if(heap_capacity(heap) * HEAP_LOAD_FACTOR <= heap_size(heap)) { heap_resize(heap); } unsigned int next_index = heap_last_index(heap) + 1; heap_set(heap, next_index, value); heap->size++; heap_bubble_up(heap, next_index); }
void heap_push(Heap *heap, void *data, float cost) { int current; current = ++heap->tail; if (heap->tail >= heap->size) { heap->size += INITIAL_HEAP_SIZE; heap->buffer = realloc(heap->buffer, sizeof(HeapItem) * heap->size); } heap->buffer[current].cost = cost; heap->buffer[current].data = data; heap_bubble_up(heap, current); }
void heap_update(Heap *heap, void *data, float new_cost) { int i; int current; current = -1; for (i = 0; i < heap->tail; i++) { if (heap->buffer[i].data == data) { current = i; break; } } if (current == -1) { heap_push(heap, data, new_cost); } else { heap_bubble_up(heap, current); } }
/* return a list of nodes representing the shortest path from v * we can't have negative edges, distances are either an overestimate * or exact (that's why we don't update downstream nodes */ void graph_explore_dijkstra(graph_t *g, graph_vertex_t *s, graph_vertex_t *e, visit_func_t visit) { /* clear graph search assets unless we're exploring the whole graph */ if (g) graph_clear_pathtrace(g); /* mark starting point's prev as a self reference to avoid looping back */ s->path.prev = s; /* just a simple queue for breadth first search */ heap_t *prioq = heap_init(NULL, (cmp_func_t)min_path_cmp); heap_insert(prioq, s); while ((s = heap_pop(prioq))) { int clock = 0; list_node_t *it; /* break if searching for a specific destination */ if (e && e == s) break; s->path.visited = 1; s->path.pre_clock = clock++; if (visit) visit(s); for (it = s->edges->first; it != NULL; it = it->next) { graph_edge_t *ve = (graph_edge_t *)it->data; graph_vertex_t *v = ve->connection; if (!v->path.prev || v->path.distance > s->path.distance + ve->weight) { v->path.prev = s; v->path.distance = s->path.distance + ve->weight; /* check if destination is already on the heap */ ssize_t idx = heap_find(prioq, v); if (idx != -1) heap_bubble_up(prioq, v, idx); else heap_insert(prioq, v); } } } heap_destroy(prioq); }
void ff_avfilter_graph_update_heap(AVFilterGraph *graph, AVFilterLink *link) { heap_bubble_up (graph, link, link->age_index); heap_bubble_down(graph, link, link->age_index); }