Dijkstra's algorithm: Difference between revisions

→‎{{header|C}}: Make the heap functions unaware of the graph
(→‎{{header|C}}: do not store vertex index in the vertex)
(→‎{{header|C}}: Make the heap functions unaware of the graph)
Line 362:
 
=={{header|C}}==
StandardThe binary heap-as-priority queue affair.is implemented Onlyas thata eachbinary nodeheap. linksThe backheap tostores an index into its heapdata positionarray, forso easierit can quickly update the weight of an item already in it.
 
<lang c>#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <stdarg.h>
 
typedef struct {
Line 378 ⟶ 377:
int edges_len;
int edges_size;
int hindex;
int dist;
int prev;
Line 391 ⟶ 389:
 
typedef struct {
int *verticesdata;
int hindex*prio;
int i, j*index;
int len;
int size;
Line 400:
int size = g->vertices_size * 2 > i ? g->vertices_size * 2 : i + 4;
g->vertices = realloc(g->vertices, size * sizeof (vertex_t *));
for (int j = g->vertices_size; j < size; j++) {
g->vertices[j] = NULL;
}
g->vertices_size = size;
}
Line 427 ⟶ 426:
}
 
void up_heap (heap_t *h, graph_t *g,create_heap (int in) {
vertex_theap_t *vh = g->vertices[i]calloc(1, sizeof (heap_t));
h->data = calloc(n + 1, sizeof (int));
int j = v->hindex;
int kh->prio = jcalloc(n /+ 21, sizeof (int));
whileh->index = calloc(jn, >sizeof 1(int) {);
return ih;
vertex_t *u = g->vertices[h->vertices[k]];
if (u->dist < v->dist)
break;
h->vertices[j] = h->vertices[k];
u->hindex = j;
j = k;
k = k / 2;
}
h->vertices[j] = i;
v->hindex = j;
}
 
void push_heap (heap_t *h, graph_tint *gv, int ip) {
vertex_tint *vi = gh->verticesindex[iv] || ++h->len;
ifint (!v->hindex)j {= i / 2;
while (i if (h->len + 1 >= h->size) {
if (h->size = h->size ? h->size * 2prio[j] :< 4;p)
break;
h->vertices = realloc(h->vertices, h->size * sizeof (int));
}h->data[i] = h->data[j];
h->len++prio[i] = h->prio[j];
vh->hindex = index[h->lendata[i]] = i;
}i = j;
int j = v->hindexj / 2;
}
up_heap(h,->data[i] g,= i)v;
uh->hindexprio[i] = jp;
h->verticesindex[jv] = i;
}
 
int min (heap_t *h, graph_tint *gi, int nj, ...int k) {
va_listint argsm = i;
if (j <= h->len && h->prio[j] < h->prio[m])
va_start(args, n);
int m = va_arg(args, int)j;
if (k <= h->len && h->prio[k] < h->prio[m])
int i, j;
for (i = 0; im <= n - 1k; i++) {
j = va_arg(args, int);
if (j > h->len)
break;
vertex_t *v = g->vertices[h->vertices[m]];
vertex_t *u = g->vertices[h->vertices[j]];
if (u->dist < v->dist)
m = j;
}
va_end(args);
return m;
}
 
voidint down_heappop_heap (heap_t *h, graph_t *g) {
int kv = h->verticesdata[1];
h->verticesdata[1] = h->verticesdata[h->len];
h->prio[1] = h->prio[h->len];
h->index[h->data[1]] = 1;
h->len--;
int i = 1;
while (1) {
int j = min(h, g, 3, i, 2 * i, 2 * i + 1);
if (j == i)
break;
h->verticesdata[i] = h->verticesdata[j];
g->vertices[h->verticesprio[i]]->hindex = ih->prio[j];
h->index[h->data[i]] = i;
i = j;
}
h->verticesdata[i] = kh->data[h->len + 1];
gh->verticesprio[ki] = h->hindexprio[h->len =+ i1];
h->index[h->data[i]] = i;
}
return v;
 
int pop_heap (heap_t *h, graph_t *g) {
int i = h->vertices[1];
h->vertices[1] = h->vertices[h->len];
h->len--;
down_heap(h, g);
return i;
}
 
Line 510 ⟶ 494:
vertex_t *v = g->vertices[a];
v->dist = 0;
heap_t *h = calloccreate_heap(1, sizeof (heap_t)g->vertices_len);
push_heap(h, ga, av->dist);
while (h->len) {
i = pop_heap(h, g);
if (i == b)
break;
Line 524 ⟶ 508:
u->prev = i;
u->dist = v->dist + e->weight;
push_heap(h, g, e->vertex, u->dist);
}
}
Line 531 ⟶ 515:
 
void print_path (graph_t *g, int i) {
int n, j = k;
vertex_t *v, *u;
i = i - 'a';
vertex_t *v = g->vertices[i], *u = v;
if (v->dist == INT_MAX) {
printf("no path\n");
return;
}
for (n = 1, vertex_tu = v; u->dist; *u = g->vertices[hu->vertices[kprev]];, n++)
int j = 1, k;
while (u->dist) { ;
char u*path = g->vertices[u->prev]malloc(n);
path[n - 1] = 'a' j++ i;
for (j = 0, vertex_tu = v; u->dist; *u = g->vertices[hu->vertices[jprev]];, j++)
}
apath[jn - kj - 2] = 'a' + u->prev;
char *a = malloc(j);
printf("%d %.*s\n", v->dist, jn, apath);
a[j - 1] = 'a' + i;
for (k = 0, u = v; k < j - 1; k++, u = g->vertices[u->prev]) {
a[j - k - 2] = 'a' + u->prev;
}
printf("%d %.*s\n", v->dist, j, a);
}
 
Line 564 ⟶ 546:
print_path(g, 'e');
return 0;
}</lang>
}
</lang>
 
output<pre>26 acde
Anonymous user