-
Notifications
You must be signed in to change notification settings - Fork 30
/
Copy pathgraph.c
141 lines (120 loc) · 3.7 KB
/
graph.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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/**
* @file graph.c
* @author hutusi ([email protected])
* @brief Refer to graph.h
* @date 2019-07-21
*
* @copyright Copyright (c) 2019, hutusi.com
*
*/
#include "graph.h"
#include "def.h"
#include "dup.h"
#include "queue.h"
#include <stdlib.h>
#include <string.h>
AdjacencyMatrix *adjacency_matrix_new(GraphType type, int num_vertexes)
{
AdjacencyMatrix *graph = (AdjacencyMatrix *)malloc(sizeof(AdjacencyMatrix));
graph->type = type;
graph->num_vertexes = num_vertexes;
graph->edges = (int **)malloc(sizeof(int *) * num_vertexes);
for (int i = 0; i < num_vertexes; ++i) {
graph->edges[i] = (int *)malloc(sizeof(int) * num_vertexes);
}
adjacency_matrix_reset(graph, -1);
return graph;
}
void adjacency_matrix_free(AdjacencyMatrix *graph)
{
for (int i = 0; i < graph->num_vertexes; ++i) {
free(graph->edges[i]);
}
free(graph->edges);
free(graph);
}
void adjacency_matrix_reset(AdjacencyMatrix *graph, int weight)
{
for (int i = 0; i < graph->num_vertexes; ++i) {
for (int j = 0; j < graph->num_vertexes; ++j) {
graph->edges[i][j] = weight;
}
}
}
void adjacency_matrix_set(AdjacencyMatrix *graph,
int vertex1,
int vertex2,
int edge)
{
graph->edges[vertex1][vertex2] = edge;
}
int adjacency_matrix_get(const AdjacencyMatrix *graph, int vertex1, int vertex2)
{
return graph->edges[vertex1][vertex2];
}
static inline void adjacency_matrix_link_internal(AdjacencyMatrix *graph, int vertex1, int vertex2)
{
graph->edges[vertex1][vertex2] = 1;
}
int adjacency_matrix_link(AdjacencyMatrix *graph, int vertex1, int vertex2)
{
adjacency_matrix_link_internal(graph, vertex1, vertex2);
if (graph->type == UndirectedUnweighted || graph->type == UndirectedWeighted) {
adjacency_matrix_link_internal(graph, vertex2, vertex1);
}
return 0;
}
static inline int
adjacency_matrix_connected(const AdjacencyMatrix *graph, int from, int to)
{
return graph->edges[from][to] >= 0;
}
int adjacency_matrix_bfs(const AdjacencyMatrix *graph, int start, int end)
{
int found = -1;
int *visited = (int *)malloc(sizeof(int) * graph->num_vertexes);
memset(visited, 0, sizeof(int) * graph->num_vertexes);
Queue *candidates = queue_new();
queue_push_tail(candidates, intdup(start));
while (queue_is_empty(candidates)) {
int *current = (int *)queue_pop_head(candidates);
visited[*current] = 1;
if (*current == end) {
free(current);
found = 0;
break;
}
for (int i = 0; i < graph->num_vertexes; ++i) {
if (adjacency_matrix_connected(graph, *current, i) && !visited[i]) {
queue_push_tail(candidates, intdup(i));
}
}
free(current);
}
queue_free(candidates);
free(visited);
return found;
}
static int adjacency_matrix_dfs_internal(const AdjacencyMatrix *graph,
int start,
int end,
int *visited)
{
if (start == end) {
return 0;
}
for (int i = 0; i < graph->num_vertexes; ++i) {
if (adjacency_matrix_connected(graph, start, i) && !visited[i]) {
adjacency_matrix_dfs_internal(graph, i, end, visited);
}
}
return -1;
}
int adjacency_matrix_dfs(const AdjacencyMatrix *graph, int start, int end)
{
int *visited = (int *)malloc(sizeof(int) * graph->num_vertexes);
memset(visited, 0, sizeof(int) * graph->num_vertexes);
int found = adjacency_matrix_dfs_internal(graph, start, end, visited);
free(visited);
return found;
}