@@ -61,14 +61,16 @@ impl Graph {
61
61
dist
62
62
}
63
63
64
- pub fn dfs ( & self , u : usize ) -> DfsIterator {
64
+ pub fn dfs ( & self , root : usize ) -> DfsIterator {
65
+ let mut visited = vec ! [ false ; self . num_v( ) ] ;
66
+ visited[ root] = true ;
65
67
let adj_iters = ( 0 ..self . num_v ( ) )
66
68
. map ( |u| self . adj_list ( u) )
67
69
. collect :: < Vec < _ > > ( ) ;
68
70
69
71
DfsIterator {
70
- visited : vec ! [ false ; self . num_v ( ) ] ,
71
- stack : vec ! [ u ] ,
72
+ visited,
73
+ stack : vec ! [ root ] ,
72
74
adj_iters,
73
75
}
74
76
}
@@ -81,32 +83,23 @@ pub struct DfsIterator<'a> {
81
83
}
82
84
83
85
impl < ' a > Iterator for DfsIterator < ' a > {
84
- type Item = usize ;
86
+ type Item = ( usize , usize ) ;
85
87
86
- /// Returns next vertex in the DFS
88
+ /// Returns next edge and vertex in the depth-first traversal
89
+ // Refs: https://www.geeksforgeeks.org/iterative-depth-first-traversal/
90
+ // https://en.wikipedia.org/wiki/Depth-first_search
87
91
fn next ( & mut self ) -> Option < Self :: Item > {
88
- // Sources:
89
- // https://www.geeksforgeeks.org/iterative-depth-first-traversal/
90
- // https://en.wikipedia.org/wiki/Depth-first_search
91
- while let Some ( & u) = self . stack . last ( ) {
92
- if let Some ( ( _, v) ) = self . adj_iters [ u] . next ( ) {
92
+ loop {
93
+ let & u = self . stack . last ( ) ?;
94
+ while let Some ( ( e, v) ) = self . adj_iters [ u] . next ( ) {
93
95
if !self . visited [ v] {
96
+ self . visited [ v] = true ;
94
97
self . stack . push ( v) ;
98
+ return Some ( ( e, v) ) ;
95
99
}
96
- } else {
97
- self . stack . pop ( ) ;
98
- }
99
-
100
- // Stack may contain same vertex twice. So
101
- // we return the popped item only
102
- // if it is not visited.
103
- if !self . visited [ u] {
104
- self . visited [ u] = true ;
105
- return Some ( u) ;
106
100
}
101
+ self . stack . pop ( ) ;
107
102
}
108
-
109
- None
110
103
}
111
104
}
112
105
@@ -153,31 +146,38 @@ mod test {
153
146
154
147
#[ test]
155
148
fn test_dfs ( ) {
156
- let mut graph = Graph :: new ( 4 , 8 ) ;
149
+ let mut graph = Graph :: new ( 4 , 6 ) ;
157
150
graph. add_edge ( 0 , 2 ) ;
158
151
graph. add_edge ( 2 , 0 ) ;
159
152
graph. add_edge ( 1 , 2 ) ;
160
153
graph. add_edge ( 0 , 1 ) ;
161
154
graph. add_edge ( 3 , 3 ) ;
162
155
graph. add_edge ( 2 , 3 ) ;
163
156
164
- let dfs_search = graph. dfs ( 2 ) . collect :: < Vec < _ > > ( ) ;
165
- assert_eq ! ( dfs_search, vec![ 2 , 3 , 0 , 1 ] ) ;
157
+ let dfs_root = 2 ;
158
+ let dfs_traversal = std:: iter:: once ( dfs_root)
159
+ . chain ( graph. dfs ( dfs_root) . map ( |( _, v) | v) )
160
+ . collect :: < Vec < _ > > ( ) ;
161
+
162
+ assert_eq ! ( dfs_traversal, vec![ 2 , 3 , 0 , 1 ] ) ;
166
163
}
167
164
168
165
#[ test]
169
166
fn test_dfs2 ( ) {
170
- let mut graph = Graph :: new ( 5 , 8 ) ;
167
+ let mut graph = Graph :: new ( 5 , 6 ) ;
171
168
graph. add_edge ( 0 , 2 ) ;
172
169
graph. add_edge ( 2 , 1 ) ;
173
170
graph. add_edge ( 1 , 0 ) ;
174
171
graph. add_edge ( 0 , 3 ) ;
175
172
graph. add_edge ( 3 , 4 ) ;
176
173
graph. add_edge ( 4 , 0 ) ;
177
174
178
- let dfs_search = graph. dfs ( 0 ) . collect :: < Vec < _ > > ( ) ;
179
- //Note this is not the only valid DFS
180
- assert_eq ! ( dfs_search, vec![ 0 , 3 , 4 , 2 , 1 ] ) ;
175
+ let dfs_root = 0 ;
176
+ let dfs_traversal = std:: iter:: once ( dfs_root)
177
+ . chain ( graph. dfs ( dfs_root) . map ( |( _, v) | v) )
178
+ . collect :: < Vec < _ > > ( ) ;
179
+
180
+ assert_eq ! ( dfs_traversal, vec![ 0 , 3 , 4 , 2 , 1 ] ) ;
181
181
}
182
182
183
183
#[ test]
@@ -190,10 +190,11 @@ mod test {
190
190
}
191
191
}
192
192
193
- let mut dfs_search = graph. dfs ( 7 ) ;
194
- let mut dfs_check = vec ! [ ] ;
195
- for _ in 0 ..num_v {
196
- dfs_check. push ( dfs_search. next ( ) . unwrap ( ) ) ;
193
+ let dfs_root = 7 ;
194
+ let mut dfs_search = graph. dfs ( dfs_root) ;
195
+ let mut dfs_check = vec ! [ dfs_root] ;
196
+ for _ in 1 ..num_v {
197
+ dfs_check. push ( dfs_search. next ( ) . unwrap ( ) . 1 ) ;
197
198
assert ! ( dfs_search. stack. len( ) <= num_v + 1 ) ;
198
199
}
199
200
0 commit comments