From 7559610a846e7dfd5d7f9a797efd898273383930 Mon Sep 17 00:00:00 2001 From: Filip Hlasek Date: Sat, 8 Aug 2020 05:28:50 -0700 Subject: [PATCH 1/2] fix: refactor BFS algorithm. (#990) * Refactor BFS algorithm. * Rename bfs. * Align the parameter padding. * Fix parameter padding * Fix typo in function name. --- graph/bfs.cpp | 62 ----------- graph/breadth_first_search.cpp | 184 +++++++++++++++++++++++++++++++++ 2 files changed, 184 insertions(+), 62 deletions(-) delete mode 100644 graph/bfs.cpp create mode 100644 graph/breadth_first_search.cpp diff --git a/graph/bfs.cpp b/graph/bfs.cpp deleted file mode 100644 index 3acee8f80..000000000 --- a/graph/bfs.cpp +++ /dev/null @@ -1,62 +0,0 @@ -#include -using namespace std; -class graph { - int v; - list *adj; - - public: - graph(int v); - void addedge(int src, int dest); - void printgraph(); - void bfs(int s); -}; -graph::graph(int v) { - this->v = v; - this->adj = new list[v]; -} -void graph::addedge(int src, int dest) { - src--; - dest--; - adj[src].push_back(dest); - // adj[dest].push_back(src); -} -void graph::printgraph() { - for (int i = 0; i < this->v; i++) { - cout << "Adjacency list of vertex " << i + 1 << " is \n"; - list::iterator it; - for (it = adj[i].begin(); it != adj[i].end(); ++it) { - cout << *it + 1 << " "; - } - cout << endl; - } -} -void graph::bfs(int s) { - bool *visited = new bool[this->v + 1]; - memset(visited, false, sizeof(bool) * (this->v + 1)); - visited[s] = true; - list q; - q.push_back(s); - list::iterator it; - while (!q.empty()) { - int u = q.front(); - cout << u << " "; - q.pop_front(); - for (it = adj[u].begin(); it != adj[u].end(); ++it) { - if (visited[*it] == false) { - visited[*it] = true; - q.push_back(*it); - } - } - } -} -int main() { - graph g(4); - g.addedge(1, 2); - g.addedge(2, 3); - g.addedge(3, 4); - g.addedge(1, 4); - g.addedge(1, 3); - // g.printgraph(); - g.bfs(2); - return 0; -} diff --git a/graph/breadth_first_search.cpp b/graph/breadth_first_search.cpp new file mode 100644 index 000000000..0f4f46160 --- /dev/null +++ b/graph/breadth_first_search.cpp @@ -0,0 +1,184 @@ +/** + * + * \file + * \brief [Breadth First Search Algorithm + * (Breadth First Search)](https://en.wikipedia.org/wiki/Breadth-first_search) + * + * \author [Ayaan Khan](http://github.com/ayaankhan98) + * + * \details + * Breadth First Search also quoted as BFS is a Graph Traversal Algorithm. + * Time Complexity O(|V| + |E|) where V are the number of vertices and E + * are the number of edges in the graph. + * + * Applications of Breadth First Search are + * + * 1. Finding shortest path between two vertices say u and v, with path + * length measured by number of edges (an advantage over depth first + * search algorithm) + * 2. Ford-Fulkerson Method for computing the maximum flow in a flow network. + * 3. Testing bipartiteness of a graph. + * 4. Cheney's Algorithm, Copying garbage collection. + * + * And there are many more... + * + *

working

+ * In the implementation below we first created a graph using the adjacency + * list representation of graph. + * Breadth First Search Works as follows + * it requires a vertex as a start vertex, Start vertex is that vertex + * from where you want to start traversing the graph. + * We maintain a bool array or a vector to keep track of the vertices + * which we have visited so that we do not traverse the visited vertices + * again and again and eventually fall into an infinite loop. Along with this + * boolen array we use a Queue. + * + * 1. First we mark the start vertex as visited. + * 2. Push this visited vertex in the Queue. + * 3. while the queue is not empty we repeat the following steps + * + * 1. Take out an element from the front of queue + * 2. Explore the adjacency list of this vertex + * if element in the adjacency list is not visited then we + * push that element into the queue and mark this as visited + * + */ +#include +#include +#include +#include +#include + +/** + * \namespace graph + * \brief Graph algorithms + */ +namespace graph { +/** + * \brief + * Adds a directed edge from vertex u to vertex v. + * + * @param graph Adjacency list representation of graph + * @param u first vertex + * @param v second vertex + * + */ +void add_directed_edge(std::vector> *graph, int u, int v) { + (*graph)[u].push_back(v); +} + +/** + * \brief + * Adds an undirected edge from vertex u to vertex v. + * Essentially adds too directed edges to the adjacency list reprsentation + * of the graph. + * + * @param graph Adjacency list representation of graph + * @param u first vertex + * @param v second vertex + * + */ +void add_undirected_edge(std::vector> *graph, int u, int v) { + add_directed_edge(graph, u, v); + add_directed_edge(graph, v, u); +} + +/** + * \brief + * Function performs the breadth first search algorithm over the graph + * + * @param graph Adjacency list representation of graph + * @param start vertex from where traversing starts + * @returns a binary vector indicating which vertices were visited during the search. + * + */ +std::vector breadth_first_search(const std::vector> &graph, + int start) { + /// vector to keep track of visited vertices + std::vector visited(graph.size(), false); + /// a queue that stores vertices that need to be further explored + std::queue tracker; + + /// mark the starting vertex as visited + visited[start] = true; + tracker.push(start); + while (!tracker.empty()) { + size_t vertex = tracker.front(); + tracker.pop(); + for (auto x : graph[vertex]) { + /// if the vertex is not visited then mark it as visited + /// and push it to the queue + if (!visited[x]) { + visited[x] = true; + tracker.push(x); + } + } + } + return visited; +} +} // namespace graph + +void tests() { + /// Test 1 Begin + std::vector> graph(4, std::vector()); + graph::add_undirected_edge(&graph, 0, 1); + graph::add_undirected_edge(&graph, 1, 2); + graph::add_undirected_edge(&graph, 2, 3); + + std::vector returned_result = graph::breadth_first_search(graph, 2); + std::vector correct_result = {true, true, true, true}; + + assert(std::equal(correct_result.begin(), correct_result.end(), + returned_result.begin())); + std::cout << "Test 1 Passed..." << std::endl; + + /// Test 2 Begin + returned_result = graph::breadth_first_search(graph, 0); + + assert(std::equal(correct_result.begin(), correct_result.end(), + returned_result.begin())); + std::cout << "Test 2 Passed..." << std::endl; + + /// Test 3 Begins + graph.clear(); + graph.resize(6); + graph::add_directed_edge(&graph, 0, 1); + graph::add_directed_edge(&graph, 0, 2); + graph::add_directed_edge(&graph, 1, 3); + graph::add_directed_edge(&graph, 2, 3); + graph::add_directed_edge(&graph, 1, 4); + graph::add_directed_edge(&graph, 3, 5); + + returned_result = graph::breadth_first_search(graph, 2); + correct_result = {false, false, true, true, false, true}; + + assert(std::equal(correct_result.begin(), correct_result.end(), + returned_result.begin())); + std::cout << "Test 3 Passed..." << std::endl; +} + +/** Main function */ +int main() { + tests(); + + size_t vertices = 0, edges = 0; + std::cout << "Enter the number of vertices: "; + std::cin >> vertices; + std::cout << "Enter the number of edges: "; + std::cin >> edges; + + std::vector> graph(vertices); + + std::cout << "Enter space-separated pairs of vertices that form edges: " + << std::endl; + while (edges--) { + int u = 0, v = 0; + std::cin >> u >> v; + // Decrement the vertex index so that we can read more convenint + // 1-based indexing from the user input. + graph::add_directed_edge(&graph, u - 1, v - 1); + } + + graph::breadth_first_search(graph, 0); + return 0; +} From 043c890524df120c1b899c0bb7157fc79b8a8761 Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Sat, 8 Aug 2020 12:30:00 +0000 Subject: [PATCH 2/2] updating DIRECTORY.md --- DIRECTORY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DIRECTORY.md b/DIRECTORY.md index 21953a553..82787cad4 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -73,7 +73,7 @@ * [Line Segment Intersection](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/geometry/line_segment_intersection.cpp) ## Graph - * [Bfs](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/bfs.cpp) + * [Breadth First Search](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/breadth_first_search.cpp) * [Bridge Finding With Tarjan Algorithm](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/bridge_finding_with_tarjan_algorithm.cpp) * [Connected Components](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/connected_components.cpp) * [Connected Components With Dsu](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/connected_components_with_dsu.cpp)