-
Notifications
You must be signed in to change notification settings - Fork 30
/
Copy pathdijkstra.c
68 lines (61 loc) · 1.93 KB
/
dijkstra.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/**
* @file dijkstra.c
* @author hutusi ([email protected])
* @brief Refer to dijkstra.h
* @date 2019-07-21
*
* @copyright Copyright (c) 2019, hutusi.com
*
*/
#include "dijkstra.h"
#include "def.h"
#include <stdlib.h>
static void dijkstra_init_distances(int *distances, int num_vertexes)
{
for (int i = 0; i < num_vertexes; ++i) {
distances[i] = -1;
}
}
static void dijkstra_refresh_candidates(const AdjacencyMatrix *graph,
int vertex,
int *distances,
int *candidates)
{
for (int i = 0; i < graph->num_vertexes; ++i) {
int edge = adjacency_matrix_get(graph, vertex, i);
/** if distances[i] > 0, the vertex has been selected */
if (edge >= 0 && distances[i] < 0) {
int new_weight = distances[vertex] + edge;
if (candidates[i] < 0 || candidates[i] > new_weight) {
candidates[i] = new_weight;
}
}
}
candidates[vertex] = -1;
}
static int dijkstra_select_vertex(int *candidates, int num_vertexes)
{
int weight = -1;
int vertex = -1;
for (int i = 0; i < num_vertexes; ++i) {
if (candidates[i] >= 0 && (weight == -1 || weight > candidates[i])) {
weight = candidates[i];
vertex = i;
}
}
return vertex;
}
void dijkstra(const AdjacencyMatrix *graph, int vertex, int *distances)
{
dijkstra_init_distances(distances, graph->num_vertexes);
int *candidates = (int *)malloc(sizeof(int *) * graph->num_vertexes);
dijkstra_init_distances(candidates, graph->num_vertexes);
int select = vertex;
candidates[vertex] = 0;
while (select >= 0) {
distances[select] = candidates[select];
dijkstra_refresh_candidates(graph, select, distances, candidates);
select = dijkstra_select_vertex(candidates, graph->num_vertexes);
}
free(candidates);
}