@@ -213,6 +213,8 @@ impl<T> Node<T> {
213213#[ derive( Clone ) ]
214214pub struct Tree < T > {
215215 nodes : Vec < Node < T > > ,
216+ /// Stack for traverse_mut to avoid allocations
217+ stack : Vec < ( usize , bool ) > ,
216218}
217219
218220impl < T > Default for Tree < T > {
@@ -234,7 +236,10 @@ impl<T> Tree<T> {
234236 /// let tree: Tree<i32> = Tree::new();
235237 /// ```
236238 pub fn new ( ) -> Self {
237- Self { nodes : Vec :: new ( ) }
239+ Self {
240+ nodes : Vec :: new ( ) ,
241+ stack : Vec :: new ( ) ,
242+ }
238243 }
239244
240245 /// Adds a new node to the tree.
@@ -523,6 +528,42 @@ impl<T> Tree<T> {
523528 }
524529 }
525530
531+ /// Walks the tree recursively, applying the given functions before and after processing the
532+ /// children of each node. This version allows for mutable access to the nodes.
533+ pub fn traverse_mut < S > (
534+ & mut self ,
535+ mut before_processing_children : impl FnMut ( usize , & mut T , & mut S ) ,
536+ mut after_processing_the_subtree : impl FnMut ( usize , & mut T , & mut S ) ,
537+ s : & mut S ,
538+ ) {
539+ if self . is_empty ( ) {
540+ return ;
541+ }
542+
543+ self . stack . clear ( ) ;
544+ self . stack . push ( ( 0 , false ) ) ;
545+
546+ while let Some ( ( index, children_visited) ) = self . stack . pop ( ) {
547+ if children_visited {
548+ // All children are processed, call f2
549+ let node = & mut self . nodes [ index] ;
550+ after_processing_the_subtree ( index, & mut node. data , s) ;
551+ } else {
552+ // Call f and mark this node's children for processing
553+ let node = & mut self . nodes [ index] ;
554+ before_processing_children ( index, & mut node. data , s) ;
555+
556+ // Re-push the current node with children_visited set to true
557+ self . stack . push ( ( index, true ) ) ;
558+
559+ // Push all children onto the stack
560+ for & child in node. children . iter ( ) . rev ( ) {
561+ self . stack . push ( ( child, false ) ) ;
562+ }
563+ }
564+ }
565+ }
566+
526567 /// Returns an iterator over the indices and data of the nodes in the tree.
527568 pub fn iter ( & self ) -> impl Iterator < Item = ( usize , & T ) > {
528569 self . nodes
@@ -646,13 +687,10 @@ mod tests {
646687 let mut result = vec ! [ ] ;
647688
648689 tree. traverse (
649- |index, node, result| {
650- result. push ( format ! ( "Calling handler for node {}: {}" , index, node) )
651- } ,
690+ |index, node, result| result. push ( format ! ( "Calling handler for node {index}: {node}" ) ) ,
652691 |index, _node, result| {
653692 result. push ( format ! (
654- "Finished handling node {} and all it's children" ,
655- index
693+ "Finished handling node {index} and all its children"
656694 ) )
657695 } ,
658696 & mut result,
@@ -664,11 +702,11 @@ mod tests {
664702 "Calling handler for node 0: 0" ,
665703 "Calling handler for node 1: 1" ,
666704 "Calling handler for node 3: 3" ,
667- "Finished handling node 3 and all it's children" ,
668- "Finished handling node 1 and all it's children" ,
705+ "Finished handling node 3 and all its children" ,
706+ "Finished handling node 1 and all its children" ,
669707 "Calling handler for node 2: 2" ,
670- "Finished handling node 2 and all it's children" ,
671- "Finished handling node 0 and all it's children" ,
708+ "Finished handling node 2 and all its children" ,
709+ "Finished handling node 0 and all its children" ,
672710 ]
673711 ) ;
674712 }
0 commit comments