-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgraph.hpp
80 lines (65 loc) · 2.08 KB
/
graph.hpp
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
#ifndef J_GRAPH
#define J_GRAPH
#include <list>
#include <map>
#include <exception>
#include <iostream>
#include <vector>
#include <unordered_map>
#define DEBUG 1
template<class T>
bool default_equals(T a, T b){
return a == b;
}
template<class T>
class graph{
private:
graph();
const std::vector<T> nodes;
const std::map<T, std::vector<T>> neighbors;
bool (*equals)(T, T);
public:
graph(std::vector<T> graph_nodes, std::map<T, std::vector<T>> graph_neighbors) : nodes(graph_nodes), neighbors(graph_neighbors), equals([](T a, T b){return a == b;}) {}
graph(std::vector<T> graph_nodes, std::map<T, std::vector<T>> graph_neighbors, bool (*equals_function)(T, T)) : nodes(graph_nodes), neighbors(graph_neighbors), equals(equals_function) {}
std::list<T> bfs(const T & start, const T & end) const{
std::map<T, bool> visited = std::map<T, bool>();
std::map<T, T const *> last_node = std::map<T,T const *>();
for (T edge : this->nodes)
visited[edge] = false;
T const * current_element = &start;
T const * last_element = nullptr;
std::list<T const *> queue;
visited[*current_element] = true;
queue.push_back(current_element);
while(!queue.empty()){
current_element = queue.front();
queue.pop_front();
if(equals(*current_element, end)){
last_element = current_element;
break;
}
for(const T & neighbor : this->neighbors.find(*current_element)->second){
if(DEBUG){
if(visited.find(neighbor) == visited.end()){
std::clog << neighbor << " was not in the map, even though it should be." << std::endl;
}
}
if(!visited[neighbor]){
visited[neighbor] = true;
queue.push_back(&neighbor);
last_node[neighbor] = current_element;
}
}
}
if(last_element == nullptr){
return std::list<T>();
}
std::list<T> answer = std::list<T>({*last_element});
while(*last_node[answer.front()] != start){
answer.push_front(*last_node[answer.front()]);
}
answer.push_front(start);
return answer;
}
};
#endif