1use super::{GraphRef, IntoNodeIdentifiers, Reversed};
2use super::{IntoNeighbors, IntoNeighborsDirected, VisitMap, Visitable};
3use crate::Incoming;
4
5#[cfg(feature = "std")]
6use std::collections::VecDeque;
7
8#[cfg(not(feature = "std"))]
9use alloc::{collections::VecDeque, vec::Vec};
10
11#[derive(Clone, Debug)]
42pub struct Dfs<N, VM> {
43 pub stack: Vec<N>,
45 pub discovered: VM,
47}
48
49impl<N, VM> Default for Dfs<N, VM>
50where
51 VM: Default,
52{
53 fn default() -> Self {
54 Dfs {
55 stack: Vec::new(),
56 discovered: VM::default(),
57 }
58 }
59}
60
61impl<N, VM> Dfs<N, VM>
62where
63 N: Copy + PartialEq,
64 VM: VisitMap<N>,
65{
66 pub fn new<G>(graph: G, start: N) -> Self
69 where
70 G: GraphRef + Visitable<NodeId = N, Map = VM>,
71 {
72 let mut dfs = Dfs::empty(graph);
73 dfs.move_to(start);
74 dfs
75 }
76
77 pub fn from_parts(stack: Vec<N>, discovered: VM) -> Self {
79 Dfs { stack, discovered }
80 }
81
82 pub fn reset<G>(&mut self, graph: G)
84 where
85 G: GraphRef + Visitable<NodeId = N, Map = VM>,
86 {
87 graph.reset_map(&mut self.discovered);
88 self.stack.clear();
89 }
90
91 pub fn empty<G>(graph: G) -> Self
93 where
94 G: GraphRef + Visitable<NodeId = N, Map = VM>,
95 {
96 Dfs {
97 stack: Vec::new(),
98 discovered: graph.visit_map(),
99 }
100 }
101
102 pub fn move_to(&mut self, start: N) {
105 self.stack.clear();
106 self.stack.push(start);
107 }
108
109 pub fn next<G>(&mut self, graph: G) -> Option<N>
111 where
112 G: IntoNeighbors<NodeId = N>,
113 {
114 while let Some(node) = self.stack.pop() {
115 if self.discovered.visit(node) {
116 for succ in graph.neighbors(node) {
117 if !self.discovered.is_visited(&succ) {
118 self.stack.push(succ);
119 }
120 }
121 return Some(node);
122 }
123 }
124 None
125 }
126}
127
128#[derive(Clone, Debug)]
136pub struct DfsPostOrder<N, VM> {
137 pub stack: Vec<N>,
139 pub discovered: VM,
141 pub finished: VM,
143}
144
145impl<N, VM> Default for DfsPostOrder<N, VM>
146where
147 VM: Default,
148{
149 fn default() -> Self {
150 DfsPostOrder {
151 stack: Vec::new(),
152 discovered: VM::default(),
153 finished: VM::default(),
154 }
155 }
156}
157
158impl<N, VM> DfsPostOrder<N, VM>
159where
160 N: Copy + PartialEq,
161 VM: VisitMap<N>,
162{
163 pub fn new<G>(graph: G, start: N) -> Self
166 where
167 G: GraphRef + Visitable<NodeId = N, Map = VM>,
168 {
169 let mut dfs = Self::empty(graph);
170 dfs.move_to(start);
171 dfs
172 }
173
174 pub fn empty<G>(graph: G) -> Self
176 where
177 G: GraphRef + Visitable<NodeId = N, Map = VM>,
178 {
179 DfsPostOrder {
180 stack: Vec::new(),
181 discovered: graph.visit_map(),
182 finished: graph.visit_map(),
183 }
184 }
185
186 pub fn reset<G>(&mut self, graph: G)
188 where
189 G: GraphRef + Visitable<NodeId = N, Map = VM>,
190 {
191 graph.reset_map(&mut self.discovered);
192 graph.reset_map(&mut self.finished);
193 self.stack.clear();
194 }
195
196 pub fn move_to(&mut self, start: N) {
199 self.stack.clear();
200 self.stack.push(start);
201 }
202
203 pub fn next<G>(&mut self, graph: G) -> Option<N>
205 where
206 G: IntoNeighbors<NodeId = N>,
207 {
208 while let Some(&nx) = self.stack.last() {
209 if self.discovered.visit(nx) {
210 for succ in graph.neighbors(nx) {
212 if !self.discovered.is_visited(&succ) {
213 self.stack.push(succ);
214 }
215 }
216 } else {
217 self.stack.pop();
218 if self.finished.visit(nx) {
219 return Some(nx);
221 }
222 }
223 }
224 None
225 }
226}
227
228#[derive(Clone)]
258pub struct Bfs<N, VM> {
259 pub stack: VecDeque<N>,
261 pub discovered: VM,
263}
264
265impl<N, VM> Default for Bfs<N, VM>
266where
267 VM: Default,
268{
269 fn default() -> Self {
270 Bfs {
271 stack: VecDeque::new(),
272 discovered: VM::default(),
273 }
274 }
275}
276
277impl<N, VM> Bfs<N, VM>
278where
279 N: Copy + PartialEq,
280 VM: VisitMap<N>,
281{
282 pub fn new<G>(graph: G, start: N) -> Self
285 where
286 G: GraphRef + Visitable<NodeId = N, Map = VM>,
287 {
288 let mut discovered = graph.visit_map();
289 discovered.visit(start);
290 let mut stack = VecDeque::new();
291 stack.push_front(start);
292 Bfs { stack, discovered }
293 }
294
295 pub fn next<G>(&mut self, graph: G) -> Option<N>
297 where
298 G: IntoNeighbors<NodeId = N>,
299 {
300 if let Some(node) = self.stack.pop_front() {
301 for succ in graph.neighbors(node) {
302 if self.discovered.visit(succ) {
303 self.stack.push_back(succ);
304 }
305 }
306
307 return Some(node);
308 }
309 None
310 }
311}
312
313#[derive(Clone)]
319pub struct Topo<N, VM> {
320 tovisit: Vec<N>,
321 ordered: VM,
322}
323
324impl<N, VM> Default for Topo<N, VM>
325where
326 VM: Default,
327{
328 fn default() -> Self {
329 Topo {
330 tovisit: Vec::new(),
331 ordered: VM::default(),
332 }
333 }
334}
335
336impl<N, VM> Topo<N, VM>
337where
338 N: Copy + PartialEq,
339 VM: VisitMap<N>,
340{
341 pub fn new<G>(graph: G) -> Self
344 where
345 G: IntoNodeIdentifiers + IntoNeighborsDirected + Visitable<NodeId = N, Map = VM>,
346 {
347 let mut topo = Self::empty(graph);
348 topo.extend_with_initials(graph);
349 topo
350 }
351
352 fn extend_with_initials<G>(&mut self, g: G)
353 where
354 G: IntoNodeIdentifiers + IntoNeighborsDirected<NodeId = N>,
355 {
356 self.tovisit.extend(
358 g.node_identifiers()
359 .filter(move |&a| g.neighbors_directed(a, Incoming).next().is_none()),
360 );
361 }
362
363 fn empty<G>(graph: G) -> Self
367 where
368 G: GraphRef + Visitable<NodeId = N, Map = VM>,
369 {
370 Topo {
371 ordered: graph.visit_map(),
372 tovisit: Vec::new(),
373 }
374 }
375
376 pub fn reset<G>(&mut self, graph: G)
378 where
379 G: IntoNodeIdentifiers + IntoNeighborsDirected + Visitable<NodeId = N, Map = VM>,
380 {
381 graph.reset_map(&mut self.ordered);
382 self.tovisit.clear();
383 self.extend_with_initials(graph);
384 }
385
386 pub fn next<G>(&mut self, g: G) -> Option<N>
392 where
393 G: IntoNeighborsDirected + Visitable<NodeId = N, Map = VM>,
394 {
395 while let Some(nix) = self.tovisit.pop() {
397 if self.ordered.is_visited(&nix) {
398 continue;
399 }
400 self.ordered.visit(nix);
401 for neigh in g.neighbors(nix) {
402 if Reversed(g)
405 .neighbors(neigh)
406 .all(|b| self.ordered.is_visited(&b))
407 {
408 self.tovisit.push(neigh);
409 }
410 }
411 return Some(nix);
412 }
413 None
414 }
415}
416
417pub trait Walker<Context> {
423 type Item;
424 fn walk_next(&mut self, context: Context) -> Option<Self::Item>;
426
427 fn iter(self, context: Context) -> WalkerIter<Self, Context>
429 where
430 Self: Sized,
431 Context: Clone,
432 {
433 WalkerIter {
434 walker: self,
435 context,
436 }
437 }
438}
439
440#[derive(Clone, Debug)]
442pub struct WalkerIter<W, C> {
443 walker: W,
444 context: C,
445}
446
447impl<W, C> WalkerIter<W, C>
448where
449 W: Walker<C>,
450 C: Clone,
451{
452 pub fn context(&self) -> C {
453 self.context.clone()
454 }
455
456 pub fn inner_ref(&self) -> &W {
457 &self.walker
458 }
459
460 pub fn inner_mut(&mut self) -> &mut W {
461 &mut self.walker
462 }
463}
464
465impl<W, C> Iterator for WalkerIter<W, C>
466where
467 W: Walker<C>,
468 C: Clone,
469{
470 type Item = W::Item;
471 fn next(&mut self) -> Option<Self::Item> {
472 self.walker.walk_next(self.context.clone())
473 }
474}
475
476impl<'a, C, W: ?Sized> Walker<C> for &'a mut W
477where
478 W: Walker<C>,
479{
480 type Item = W::Item;
481 fn walk_next(&mut self, context: C) -> Option<Self::Item> {
482 (**self).walk_next(context)
483 }
484}
485
486impl<G> Walker<G> for Dfs<G::NodeId, G::Map>
487where
488 G: IntoNeighbors + Visitable,
489{
490 type Item = G::NodeId;
491 fn walk_next(&mut self, context: G) -> Option<Self::Item> {
492 self.next(context)
493 }
494}
495
496impl<G> Walker<G> for DfsPostOrder<G::NodeId, G::Map>
497where
498 G: IntoNeighbors + Visitable,
499{
500 type Item = G::NodeId;
501 fn walk_next(&mut self, context: G) -> Option<Self::Item> {
502 self.next(context)
503 }
504}
505
506impl<G> Walker<G> for Bfs<G::NodeId, G::Map>
507where
508 G: IntoNeighbors + Visitable,
509{
510 type Item = G::NodeId;
511 fn walk_next(&mut self, context: G) -> Option<Self::Item> {
512 self.next(context)
513 }
514}
515
516impl<G> Walker<G> for Topo<G::NodeId, G::Map>
517where
518 G: IntoNeighborsDirected + Visitable,
519{
520 type Item = G::NodeId;
521 fn walk_next(&mut self, context: G) -> Option<Self::Item> {
522 self.next(context)
523 }
524}