-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTraversal.h
63 lines (56 loc) · 1.42 KB
/
Traversal.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#pragma once
#include "SValue.h"
#include <queue>
#include <stack>
template < typename UnaryOp >
void traversePreorder( SValue& r, UnaryOp f )
{
std::stack< SValue* > traversal;
traversal.push( &r );
while ( !traversal.empty() )
{
SValue* n = traversal.top();
traversal.pop();
f( *n );
n->foreachCell( [ &traversal ]( SValue& child ) { traversal.push( &child ); } );
}
}
template < typename UnaryOp >
void traversePreorder( const SValue& r, UnaryOp f )
{
std::stack< const SValue* > traversal;
traversal.push( &r );
while ( !traversal.empty() )
{
const SValue* n = traversal.top();
traversal.pop();
f( *n );
n->foreachCell( [ &traversal ]( const SValue& child ) { traversal.push( &child ); } );
}
}
template < typename CompareOp >
void traverseLevelOrder( const SValue& r, CompareOp f )
{
std::queue< const SValue* > traversal;
traversal.push( &r );
std::size_t level = 0;
std::size_t queuedCount = 0;
while ( !traversal.empty() )
{
// Keep dequeuing from the current level.
if ( queuedCount > 0 )
{
queuedCount -= 1;
}
// Once we dequeued the entire level, we go down a level.
if ( queuedCount == 0 )
{
queuedCount = traversal.size();
level += 1;
}
const SValue* n = traversal.front();
traversal.pop();
f( *n, level );
n->foreachCell( [ &traversal ]( const SValue& child ) { traversal.push( &child ); } );
}
}