Because both depth_first_search
and undirected_dfs
pass DFSVisitor vis
by value, we cannot use std::vector<>
to store traversed vertices, otherwise its size will always be 0 after exiting depth_first_search
or undirected_dfs
. Instead, we can use a std::shared_ptr<std::vector<>>
or static std::vector<>
to store the vertices. In my opinion, using a static
data member is simpler and more expressive.
Here we can get pre-order traversal with discover_vertex()
and post-order traversal with finish_vertex
. See DFS Visitor for more details.
Live on Coliru
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/depth_first_search.hpp>
#include <iostream>
using MyGraph = boost::adjacency_list<
boost::listS, boost::vecS, boost::undirectedS,
boost::property<boost::vertex_color_t, boost::default_color_type>>;
using MyVertex = boost::graph_traits<MyGraph>::vertex_descriptor;
struct MyDFSVisitor : public boost::default_dfs_visitor {
inline static std::vector<MyVertex> m_preorder_vertices;
inline static std::vector<MyVertex> m_postorder_vertices;
void discover_vertex(MyVertex v, const MyGraph &g) {
m_preorder_vertices.push_back(v);
}
void finish_vertex(MyVertex v, const MyGraph &g) {
m_postorder_vertices.push_back(v);
}
};
int main() {
MyGraph g{};
boost::add_edge(0, 1, g);
boost::add_edge(0, 2, g);
boost::add_edge(1, 2, g);
boost::add_edge(1, 3, g);
auto root = boost::vertex(0, g);
auto color_map = boost::get(boost::vertex_color, g);
MyDFSVisitor vis;
boost::depth_first_search(g, vis, color_map, root);
std::cout << "pre-order traversal : \n"; // 0 1 2 3
for (auto v : vis.m_preorder_vertices) {
std::cout << v << std::endl;
}
std::cout << "post-order traversal : \n"; // 2 3 1 0
for (auto v : vis.m_postorder_vertices) {
std::cout << v << std::endl;
}
}
Note that inline static
is a C++17 feature.