1use std::fmt::Debug;
2use std::collections::HashSet;
3
4#[derive(Debug)]
9pub struct Graph {
10 adjacent_list: Vec<Vec<usize>>,
11 indegree: Vec<usize>,
12 num_nodes: usize,
13}
14
15impl Graph {
16
17 pub fn new(num_nodes: usize, routes: Vec<(usize, usize)>) -> Self {
28 let mut adjacent_list = vec![Vec::<usize>::new(); num_nodes];
29 let mut indegree = vec![0; num_nodes];
30 for route in routes {
31 let source = route.1;
32 let target = route.0;
33 adjacent_list[source].push(target);
34 indegree[target] += 1;
35 }
36 Graph {
37 adjacent_list,
38 indegree,
39 num_nodes,
40 }
41 }
42
43 pub fn is_acyclic_bfs(&self) -> bool {
56 for v in 0..self.num_nodes {
57 let mut queue = Vec::new();
59 let mut seens = HashSet::new();
60 let mut visit = Vec::new();
61 visit.push(v);
62
63 let adjacent = &self.adjacent_list[v];
64 for &neighbor in adjacent {
65 queue.push(neighbor);
66 }
67
68 while queue.len() > 0 {
69 let vertex = queue.pop().unwrap();
70 if vertex == v {
71 return false;
72 }
73
74 if !seens.contains(&vertex) {
75 visit.push(vertex);
77 seens.insert(vertex);
78 }
79
80 let adjacent = &self.adjacent_list[vertex];
81 for neighbor in adjacent {
82 if !seens.contains(neighbor) {
83 queue.push(*neighbor);
84 }
85 }
86 }
87 }
89 true
90 }
91
92 pub fn is_acyclic_top_sort(&mut self) -> bool {
105 let mut queue = Vec::new();
106 for i in 0..self.num_nodes {
107 if self.indegree[i] == 0 {
108 queue.push(i);
109 }
110 }
111 let mut count = 0;
112 while !queue.is_empty() {
113 let vertex = queue.pop().unwrap();
114 count += 1;
115 let adjacent = &self.adjacent_list[vertex];
116 for &neighbor in adjacent {
117 self.indegree[neighbor] -= 1;
118 if self.indegree[neighbor] == 0 {
119 queue.push(neighbor);
120 }
121 }
122 }
123 self.num_nodes == count
124 }
125
126 pub fn breadth_first_search(&self, start: usize) -> Vec<usize> {
139 let mut queue = Vec::new();
140 let mut visit = Vec::new();
141 let mut seens = HashSet::new();
142 queue.push(start);
143
144 while !queue.is_empty() {
145 let vertex = queue.pop().unwrap();
147 if seens.contains(&vertex) {
148 continue;
149 }
150 seens.insert(vertex);
151 visit.push(vertex);
152 let adjacent = &self.adjacent_list[vertex];
153 for neighbor in adjacent {
154 if !seens.contains(neighbor) {
155 queue.push(*neighbor);
156 }
157 }
158 }
159 visit
160 }
161
162 pub fn depth_first_search(&self, vertex: usize) -> Vec<usize> {
178 let adjacent = &self.adjacent_list[vertex];
179 if adjacent.is_empty() {
180 return vec![vertex];
181 }
182 let mut visit = Vec::new();
183 for &neighbor in adjacent {
184 visit.append(&mut self.depth_first_search(neighbor));
185 }
186 visit.push(vertex);
187 visit
188 }
189}
190
191#[cfg(test)]
192mod tests {
193 use super::*;
194
195 #[test]
196 fn test_graph() {
197 let graph = Graph::new(6, vec![(1, 0), (2, 1), (2, 5), (0, 3), (4, 3), (3, 5), (4, 5)]);
198 println!("graph: {:?}", graph);
199 }
201
202 #[test]
203 fn test_is_acyclic_graph() {
204 let graph = Graph::new(6, vec![(1, 0), (2, 1), (2, 5), (0, 3), (4, 3), (3, 5), (4, 5)]);
205 println!("graph: {:?}", graph);
206 assert_eq!(graph.is_acyclic_bfs(), true);
207 }
209
210 #[test]
211 fn test_is_acyclic_top_sort() {
212 let mut graph = Graph::new(6, vec![(1, 0), (2, 1), (2, 5), (0, 3), (4, 3), (3, 5), (4, 5)]);
213 println!("graph: {:?}", graph);
214 assert_eq!(graph.is_acyclic_top_sort(), true);
215 }
216
217 #[test]
218 fn test_bfs() {
219 let graph = Graph::new(6, vec![(1, 0), (2, 1), (2, 5), (0, 3), (4, 3), (3, 5), (4, 5)]);
220 let visit = graph.breadth_first_search(5);
221 println!("graph: {:?}", graph);
222 println!("bfs: {:?}", visit);
223 assert_eq!(visit, vec![5, 4, 3, 0, 1, 2]);
224 }
225
226 #[test]
227 fn test_dfs() {
228 let graph = Graph::new(8, vec![
229 (5, 4), (2, 4), (6, 4),
230 (7, 5), (0, 2), (1, 2), (3, 6)
231 ]);
232 let visit = graph.depth_first_search(4);
233 println!("graph: {:?}", graph);
234 println!("dfs: {:?}", visit);
235 assert_eq!(visit, vec![7, 5, 0, 1, 2, 3, 6, 4]);
236 }
237}