您的要求似乎矛盾:
这正是深度优先遍历 (DFS) 的典型特征
- 在随后的运行中,我想再次遍历,但使用
每个级别的交替分支。分支切换从顶部发生
先向下传播。
这是典型的广度优先遍历 (BFS)
我可以向您展示带有 Boost 的标准 BFS/DFS,但如果您想要自己的混合算法,您可能必须自己编写。我的猜测是您实际上想要 BFS¹
代码
- 我有一个结构类似于树根的固定图:单头,向下多级,大多数级别有单个节点,一些级别有兄弟节点。没有循环分支。
auto make_graph() {
enum { root, a, b, c, d, e, f, g, h, i, j };
boost::adjacency_list<> graph(j+1);
add_edge(root, a, graph);
add_edge(root, b, graph);
add_edge(root, c, graph);
add_edge(a, d, graph);
add_edge(a, e, graph);
add_edge(d, f, graph);
add_edge(b, h, graph);
add_edge(h, i, graph);
add_edge(i, j, graph);
return graph;
}
对应于
进行遍历:
最简单的 BFS 是:
int main() {
Graph const graph = make_graph();
boost::default_bfs_visitor vis;
std::vector<boost::default_color_type> colors(num_vertices(graph));
boost::breadth_first_visit(graph, Vertex{ root },
boost::visitor(vis).color_map(colors.data()));
}
这使用默认访问者,它实际上什么都不做。
您可以覆盖任何事件,例如:
struct Vis : boost::default_bfs_visitor {
void discover_vertex(Vertex u, Graph const&) {
std::cout << "Discover " << names[u] << "\n";
}
void examine_vertex(Vertex u, Graph const& g) {
if (0 == out_degree(u, g)) {
std::cout << "Examine Leaf Node " << names[u] << "\n";
}
}
using Edge = Graph::edge_descriptor;
void tree_edge(Edge e, Graph const& g) const {
auto a = source(e, g);
auto b = target(e, g);
std::cout << "Tree edge " << names[a] << " -> " << names[b] << "\n";
}
} vis;
全部启用后将打印:
Discover root
Tree edge root -> a
Discover a
Tree edge root -> b
Discover b
Tree edge root -> c
Discover c
Tree edge a -> d
Discover d
Tree edge a -> e
Discover e
Tree edge b -> h
Discover h
Examine Leaf Node c
Tree edge d -> f
Discover f
Examine Leaf Node e
Tree edge h -> i
Discover i
Examine Leaf Node f
Tree edge i -> j
Discover j
Examine Leaf Node j
事件的完整文档在这里:https://www.boost.org/doc/libs/1_73_0/libs/graph/doc/BFSVisitor.html
¹(因为即便如此,仍然会首先报告第一个叶子,因此可能无法观察到它访问其他正在进行的节点的事实)