sub traverse_tree { my ( $tree_root, $visitor_callback ) = @_; my ( $curr_node, $prev_node ) = $tree_root; while( $curr_node ) { my $next_node; if( $prev_node == $curr_node->parent ) { $next_node = $curr_node->left; if( not $next_node ) { $visitor_callback->( $curr_node ); $next_node = $curr_node->right || $curr_node->parent; } } elsif( $prev_node == $curr_node->left ) { $visitor_callback->( $curr_node ); $next_node = $curr_node->right || $curr_node->parent; } elsif( $prev_node == $curr_node->right ) { $next_node = $curr_node->parent; } ( $prev_node, $curr_node ) = ( $curr_node, $next_node ); } } #### sub traverse_tree { my ( $tree_root, $visitor_callback ) = @_; my ( $curr_node, $prev_node ) = $tree_root; while( $curr_node ) { my $next_node; { goto FROM_PARENT if $prev_node == $curr_node->parent; goto FROM_LEFT if $prev_node == $curr_node->left; goto FROM_RIGHT if $prev_node == $curr_node->right; FROM_PARENT: last if $next_node = $curr_node->left; FROM_LEFT: $visitor_callback->( $curr_node ); last if $next_node = $curr_node->right; FROM_RIGHT: $next_node = $curr_node->parent; } ( $prev_node, $curr_node ) = ( $curr_node, $next_node ); } }