mirror of
https://hub.njuu.cf/TheAlgorithms/C-Plus-Plus.git
synced 2023-10-11 13:05:55 +08:00
Merge pull request #986 from fhlasek/fixgraph
fhlasek/fixgraph: refactor of graph/ to follow the linter style
This commit is contained in:
commit
dfe5bd7638
@ -40,6 +40,7 @@ add_subdirectory(backtracking)
|
|||||||
add_subdirectory(data_structures)
|
add_subdirectory(data_structures)
|
||||||
add_subdirectory(machine_learning)
|
add_subdirectory(machine_learning)
|
||||||
add_subdirectory(numerical_methods)
|
add_subdirectory(numerical_methods)
|
||||||
|
add_subdirectory(graph)
|
||||||
|
|
||||||
cmake_policy(SET CMP0054 NEW)
|
cmake_policy(SET CMP0054 NEW)
|
||||||
cmake_policy(SET CMP0057 NEW)
|
cmake_policy(SET CMP0057 NEW)
|
||||||
|
@ -71,6 +71,7 @@
|
|||||||
* [Tree Height](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/tree_height.cpp)
|
* [Tree Height](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/tree_height.cpp)
|
||||||
|
|
||||||
## Geometry
|
## Geometry
|
||||||
|
* [Jarvis Algorithm](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/geometry/jarvis_algorithm.cpp)
|
||||||
* [Line Segment Intersection](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/geometry/line_segment_intersection.cpp)
|
* [Line Segment Intersection](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/geometry/line_segment_intersection.cpp)
|
||||||
|
|
||||||
## Graph
|
## Graph
|
||||||
@ -79,10 +80,11 @@
|
|||||||
* [Connected Components](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/connected_components.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)
|
* [Connected Components With Dsu](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/connected_components_with_dsu.cpp)
|
||||||
* [Cycle Check Directed Graph](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/cycle_check_directed_graph.cpp)
|
* [Cycle Check Directed Graph](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/cycle_check_directed_graph.cpp)
|
||||||
* [Dfs](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/dfs.cpp)
|
* [Depth First Search](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/depth_first_search.cpp)
|
||||||
* [Dfs With Stack](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/dfs_with_stack.cpp)
|
* [Depth First Search With Stack](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/depth_first_search_with_stack.cpp)
|
||||||
* [Dijkstra](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/dijkstra.cpp)
|
* [Dijkstra](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/dijkstra.cpp)
|
||||||
* [Hamiltons Cycle](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/hamiltons_cycle.cpp)
|
* [Hamiltons Cycle](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/hamiltons_cycle.cpp)
|
||||||
|
* [Is Graph Bipartite](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/is_graph_bipartite.cpp)
|
||||||
* [Kosaraju](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/kosaraju.cpp)
|
* [Kosaraju](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/kosaraju.cpp)
|
||||||
* [Kruskal](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/kruskal.cpp)
|
* [Kruskal](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/kruskal.cpp)
|
||||||
* [Lowest Common Ancestor](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/lowest_common_ancestor.cpp)
|
* [Lowest Common Ancestor](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/lowest_common_ancestor.cpp)
|
||||||
|
20
graph/CMakeLists.txt
Normal file
20
graph/CMakeLists.txt
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# If necessary, use the RELATIVE flag, otherwise each source file may be listed
|
||||||
|
# with full pathname. RELATIVE may makes it easier to extract an executable name
|
||||||
|
# automatically.
|
||||||
|
file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp )
|
||||||
|
# file( GLOB APP_SOURCES ${CMAKE_SOURCE_DIR}/*.c )
|
||||||
|
# AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_SOURCES)
|
||||||
|
foreach( testsourcefile ${APP_SOURCES} )
|
||||||
|
# I used a simple string replace, to cut off .cpp.
|
||||||
|
string( REPLACE ".cpp" "" testname ${testsourcefile} )
|
||||||
|
add_executable( ${testname} ${testsourcefile} )
|
||||||
|
|
||||||
|
set_target_properties(${testname} PROPERTIES
|
||||||
|
LINKER_LANGUAGE CXX
|
||||||
|
)
|
||||||
|
if(OpenMP_CXX_FOUND)
|
||||||
|
target_link_libraries(${testname} OpenMP::OpenMP_CXX)
|
||||||
|
endif()
|
||||||
|
install(TARGETS ${testname} DESTINATION "bin/graph")
|
||||||
|
|
||||||
|
endforeach( testsourcefile ${APP_SOURCES} )
|
@ -53,7 +53,7 @@ using AdjList = std::map<unsigned int, std::vector<unsigned int>>;
|
|||||||
*/
|
*/
|
||||||
class Graph {
|
class Graph {
|
||||||
public:
|
public:
|
||||||
Graph() : m_vertices(0), m_adjList({}) {}
|
Graph() : m_adjList({}) {}
|
||||||
~Graph() = default;
|
~Graph() = default;
|
||||||
Graph(Graph&&) = default;
|
Graph(Graph&&) = default;
|
||||||
Graph& operator=(Graph&&) = default;
|
Graph& operator=(Graph&&) = default;
|
||||||
@ -65,8 +65,8 @@ class Graph {
|
|||||||
* @param vertices specify the number of vertices the graph would contain.
|
* @param vertices specify the number of vertices the graph would contain.
|
||||||
* @param adjList is the adjacency list representation of graph.
|
* @param adjList is the adjacency list representation of graph.
|
||||||
*/
|
*/
|
||||||
Graph(unsigned int vertices, AdjList const& adjList)
|
Graph(unsigned int vertices, AdjList adjList)
|
||||||
: m_vertices(vertices), m_adjList(adjList) {}
|
: m_vertices(vertices), m_adjList(std::move(adjList)) {}
|
||||||
|
|
||||||
/** Create a graph from vertices and adjacency list.
|
/** Create a graph from vertices and adjacency list.
|
||||||
*
|
*
|
||||||
@ -142,7 +142,7 @@ class Graph {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned int m_vertices;
|
unsigned int m_vertices = 0;
|
||||||
AdjList m_adjList;
|
AdjList m_adjList;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
133
graph/depth_first_search.cpp
Normal file
133
graph/depth_first_search.cpp
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \file
|
||||||
|
* \brief [Depth First Search Algorithm
|
||||||
|
* (Depth First Search)](https://en.wikipedia.org/wiki/Depth-first_search)
|
||||||
|
*
|
||||||
|
* \author [Ayaan Khan](http://github.com/ayaankhan98)
|
||||||
|
*
|
||||||
|
* \details
|
||||||
|
* Depth First Search also quoted as DFS is a Graph Traversal Algorithm.
|
||||||
|
* Time Complexity O(|V| + |E|) where V is number of vertices and E
|
||||||
|
* is number of edges in graph.
|
||||||
|
*
|
||||||
|
* Application of Depth First Search are
|
||||||
|
*
|
||||||
|
* 1. Finding connected components
|
||||||
|
* 2. Finding 2-(edge or vertex)-connected components.
|
||||||
|
* 3. Finding 3-(edge or vertex)-connected components.
|
||||||
|
* 4. Finding the bridges of a graph.
|
||||||
|
* 5. Generating words in order to plot the limit set of a group.
|
||||||
|
* 6. Finding strongly connected components.
|
||||||
|
*
|
||||||
|
* And there are many more...
|
||||||
|
*
|
||||||
|
* <h4>Working</h4>
|
||||||
|
* 1. Mark all vertices as unvisited first
|
||||||
|
* 2. start exploring from some starting vertex.
|
||||||
|
*
|
||||||
|
* While exploring vertex we mark the vertex as visited
|
||||||
|
* and start exploring the vertices connected to this
|
||||||
|
* vertex in recursive way.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* \namespace graph
|
||||||
|
* \brief Graph Algorithms
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
namespace graph {
|
||||||
|
/**
|
||||||
|
* \brief
|
||||||
|
* Adds and edge between two vertices of graph say u and v in this
|
||||||
|
* case.
|
||||||
|
*
|
||||||
|
* @param adj Adjacency list representation of graph
|
||||||
|
* @param u first vertex
|
||||||
|
* @param v second vertex
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void addEdge(std::vector<std::vector<size_t>> *adj, size_t u, size_t v) {
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Here we are considering undirected graph that's the
|
||||||
|
* reason we are adding v to the adjacency list representation of u
|
||||||
|
* and also adding u to the adjacency list representation of v
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
(*adj)[u - 1].push_back(v - 1);
|
||||||
|
(*adj)[v - 1].push_back(u - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* \brief
|
||||||
|
* Explores the given vertex, exploring a vertex means traversing
|
||||||
|
* over all the vertices which are connected to the vertex that is
|
||||||
|
* currently being explored.
|
||||||
|
*
|
||||||
|
* @param adj garph
|
||||||
|
* @param v vertex to be explored
|
||||||
|
* @param visited already visited vertices
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void explore(const std::vector<std::vector<size_t>> &adj, size_t v,
|
||||||
|
std::vector<bool> *visited) {
|
||||||
|
std::cout << v + 1 << " ";
|
||||||
|
(*visited)[v] = true;
|
||||||
|
for (auto x : adj[v]) {
|
||||||
|
if (!(*visited)[x]) {
|
||||||
|
explore(adj, x, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief
|
||||||
|
* initiates depth first search algorithm.
|
||||||
|
*
|
||||||
|
* @param adj adjacency list of graph
|
||||||
|
* @param start vertex from where DFS starts traversing.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void depth_first_search(const std::vector<std::vector<size_t>> &adj,
|
||||||
|
size_t start) {
|
||||||
|
size_t vertices = adj.size();
|
||||||
|
|
||||||
|
std::vector<bool> visited(vertices, false);
|
||||||
|
explore(adj, start, &visited);
|
||||||
|
}
|
||||||
|
} // namespace graph
|
||||||
|
|
||||||
|
/** Main function */
|
||||||
|
int main() {
|
||||||
|
size_t vertices = 0, edges = 0;
|
||||||
|
std::cout << "Enter the Vertices : ";
|
||||||
|
std::cin >> vertices;
|
||||||
|
std::cout << "Enter the Edges : ";
|
||||||
|
std::cin >> edges;
|
||||||
|
|
||||||
|
/// creating graph
|
||||||
|
std::vector<std::vector<size_t>> adj(vertices, std::vector<size_t>());
|
||||||
|
|
||||||
|
/// taking input for edges
|
||||||
|
std::cout << "Enter the vertices which have edges between them : "
|
||||||
|
<< std::endl;
|
||||||
|
while (edges--) {
|
||||||
|
size_t u = 0, v = 0;
|
||||||
|
std::cin >> u >> v;
|
||||||
|
graph::addEdge(&adj, u, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// running depth first search over graph
|
||||||
|
graph::depth_first_search(adj, 2);
|
||||||
|
|
||||||
|
std::cout << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
46
graph/depth_first_search_with_stack.cpp
Normal file
46
graph/depth_first_search_with_stack.cpp
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <list>
|
||||||
|
#include <vector>
|
||||||
|
#include <stack>
|
||||||
|
|
||||||
|
constexpr int WHITE = 0;
|
||||||
|
constexpr int GREY = 1;
|
||||||
|
constexpr int BLACK = 2;
|
||||||
|
constexpr int INF = 99999;
|
||||||
|
|
||||||
|
void dfs(const std::vector< std::list<int> > &graph, int start) {
|
||||||
|
std::vector<int> checked(graph.size(), WHITE);
|
||||||
|
checked[start] = GREY;
|
||||||
|
std::stack<int> stack;
|
||||||
|
stack.push(start);
|
||||||
|
while (!stack.empty()) {
|
||||||
|
int act = stack.top();
|
||||||
|
stack.pop();
|
||||||
|
|
||||||
|
if (checked[act] == GREY) {
|
||||||
|
std::cout << act << ' ';
|
||||||
|
for (auto it : graph[act]) {
|
||||||
|
stack.push(it);
|
||||||
|
if (checked[it] != BLACK) {
|
||||||
|
checked[it] = GREY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
checked[act] = BLACK; // nodo controllato
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
int n = 0;
|
||||||
|
std::cin >> n;
|
||||||
|
std::vector< std::list<int> > graph(INF);
|
||||||
|
for (int i = 0; i < n; ++i) {
|
||||||
|
int u = 0, w = 0;
|
||||||
|
std::cin >> u >> w;
|
||||||
|
graph[u].push_back(w);
|
||||||
|
}
|
||||||
|
|
||||||
|
dfs(graph, 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -1,26 +0,0 @@
|
|||||||
#include <iostream>
|
|
||||||
using namespace std;
|
|
||||||
int v = 4;
|
|
||||||
void DFSUtil_(int graph[4][4], bool visited[], int s) {
|
|
||||||
visited[s] = true;
|
|
||||||
cout << s << " ";
|
|
||||||
for (int i = 0; i < v; i++) {
|
|
||||||
if (graph[s][i] == 1 && visited[i] == false) {
|
|
||||||
DFSUtil_(graph, visited, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DFS_(int graph[4][4], int s) {
|
|
||||||
bool visited[v];
|
|
||||||
memset(visited, 0, sizeof(visited));
|
|
||||||
DFSUtil_(graph, visited, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
int graph[4][4] = {{0, 1, 1, 0}, {0, 0, 1, 0}, {1, 0, 0, 1}, {0, 0, 0, 1}};
|
|
||||||
cout << "DFS: ";
|
|
||||||
DFS_(graph, 2);
|
|
||||||
cout << endl;
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,51 +0,0 @@
|
|||||||
#include <iostream>
|
|
||||||
#include <list>
|
|
||||||
#include <stack>
|
|
||||||
|
|
||||||
#define WHITE 0
|
|
||||||
#define GREY 1
|
|
||||||
#define BLACK 2
|
|
||||||
#define INF 99999
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
int checked[999] = {WHITE};
|
|
||||||
|
|
||||||
void dfs(const list<int> lista[], int start) {
|
|
||||||
stack<int> stack;
|
|
||||||
|
|
||||||
int checked[999] = {WHITE};
|
|
||||||
|
|
||||||
stack.push(start);
|
|
||||||
|
|
||||||
checked[start] = GREY;
|
|
||||||
while (!stack.empty()) {
|
|
||||||
int act = stack.top();
|
|
||||||
stack.pop();
|
|
||||||
|
|
||||||
if (checked[act] == GREY) {
|
|
||||||
cout << act << ' ';
|
|
||||||
for (auto it = lista[act].begin(); it != lista[act].end(); ++it) {
|
|
||||||
stack.push(*it);
|
|
||||||
if (checked[*it] != BLACK)
|
|
||||||
checked[*it] = GREY;
|
|
||||||
}
|
|
||||||
checked[act] = BLACK; // nodo controllato
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
int u, w;
|
|
||||||
int n;
|
|
||||||
cin >> n;
|
|
||||||
list<int> lista[INF];
|
|
||||||
for (int i = 0; i < n; ++i) {
|
|
||||||
cin >> u >> w;
|
|
||||||
lista[u].push_back(w);
|
|
||||||
}
|
|
||||||
|
|
||||||
dfs(lista, 0);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user