algods/graph/processing/search/
first_search.rs

1use crate::graph::VertexInfo;
2use std::collections::LinkedList;
3
4/// Function that runs the depth-first search algorithm
5pub fn dfs<G>(
6    graph: &G,
7    marked: &mut [bool],
8    edge_to: &mut Vec<usize>,
9    origin: usize,
10    component: usize,
11    mut_edge_to: bool, // indicates whether or not not mutate edge_to
12    is_component: bool, // indicates whether or not to dfs is launched
13                       // for connected component-like algorithms
14) where
15    G: VertexInfo,
16{
17    // finds all reachable vertices from origin and adds them to the connected component w
18    // run time complexity O(sum of degrees of all reachable vertices from origin)
19    assert!(VertexInfo::nb_vertices(graph) >= std::cmp::max(origin, component));
20    // mark vertex w as visited
21    marked[origin] = true;
22
23    // define how to mutate the edge_to list
24    let source = if is_component { component } else { origin };
25    // recursively visit all unmarked adjacent vertices to w
26    let adjacent_vertices = graph.vertex_edges(&origin);
27    if mut_edge_to {
28        for u in adjacent_vertices {
29            if !marked[*u] {
30                dfs(
31                    graph,
32                    marked,
33                    edge_to,
34                    *u,
35                    component,
36                    mut_edge_to,
37                    is_component,
38                );
39                edge_to[*u] = source;
40            }
41        }
42    } else {
43        for u in adjacent_vertices {
44            if !marked[*u] {
45                dfs(
46                    graph,
47                    marked,
48                    edge_to,
49                    *u,
50                    component,
51                    mut_edge_to,
52                    is_component,
53                );
54            }
55        }
56        edge_to.push(origin);
57    }
58}
59
60/// Function that runs the breadth-first search algorithm
61pub fn bfs<G>(graph: &G, marked: &mut [bool], edge_to: &mut [usize], w: usize)
62where
63    G: VertexInfo,
64{
65    assert!(VertexInfo::nb_vertices(graph) >= w);
66    let mut queue = LinkedList::<usize>::new();
67    // mark the vertex w as visited and add it to the queue
68    queue.push_back(w);
69    marked[w] = true;
70
71    while let Some(x) = queue.pop_front() {
72        // remove the first vertex in the queue
73        // add to the queue all unmarked vertices adjacent to v and mark them
74        let adj_x = graph.vertex_edges(&x);
75        for u in adj_x {
76            if !marked[*u] {
77                queue.push_back(*u);
78                marked[*u] = true;
79                edge_to[*u] = x;
80            }
81        }
82    }
83}