Concept: Recursive Yield on to a Common Channel.
Let's implement a simple iterator the return all of the values of all the nodes.
The Concept
Instead of repeatedly yielding values from a deeper level of recursion.
Why not pass some form of reference to the "Yielder" mechanism the ???
Now the iterator is O(n) rather then O(n2)
Restrictions
The iterator channel reference is locally scoped, akin to the functionality of the *cough* Goto {label name} *cough* and can not be pass out of the iterator method.
Open Challenge
Can any out there find away of achieving this without building a collection as you go and yielding them, or using the ForEach ... Yield method currently being used.
Public Class Node(Of T) Public ReadOnly Value As T Public Property Left As Node(Of T) Public Property Righ As Node(Of T)
Let's implement a simple iterator the return all of the values of all the nodes.
Public Iterator Function VisitNode(Of T)( N As Node(Of T)) As IEnumerable(Of T)
Yield N.Value
If n.Left IsNot Nothing Then
For Each visitedNode In VisitNode(N.Left)
Yield visitedNode
Next
End If
If n.Righ IsNot Nothing Then
For Each visitedNode In VisitNode(N.Righ)
Yield visitedNode
Next
End If
End Function
The Concept
Instead of repeatedly yielding values from a deeper level of recursion.
Why not pass some form of reference to the "Yielder" mechanism the ???
Now the iterator is O(n) rather then O(n2)
Public Iterator Function VisitNodes(Of T)(N As Node(Of T)) As IEnumerable(Of T)
Dim _Visit = Recursive Iterator(ByRef channel As ?? ,_N As Node(Of T))
Yield On channel _N.Value
' The value isnot yielded at the local scope of '
' the lambda _Visit '
' but on iterator: VisitNodes '
If N.Left IsNot Nothing _Visit(channel, N.Left)
If N.Righ IsNot Nothing _Visit(channel, N.Righ)
End Iterator
_Visit( AddressOf(VisitNodes.Iterator), N)
End Iterator
Restrictions
The iterator channel reference is locally scoped, akin to the functionality of the *cough* Goto {label name} *cough* and can not be pass out of the iterator method.
Open Challenge
Can any out there find away of achieving this without building a collection as you go and yielding them, or using the ForEach ... Yield method currently being used.
3 Comments On This Entry
Page 1 of 1
cfoley
22 August 2012 - 10:11 AM
To be clear, do you want to do a preorder traversal without using recursion? My first instinct is to use a stack. Something like:
The concept is fairly language agnostic and I think if you implement it in VB your scoping issues will vanish.
let N = root node
let S = empty stack
while N != null
Yield N
S.push N
if N.hasLeftChild
N = N.leftChild
else if N.hasRightChild
N = N.rightChild
else if S.isEmpty
N = null
else
N = S.pop
The concept is fairly language agnostic and I think if you implement it in VB your scoping issues will vanish.
cfoley
22 August 2012 - 10:24 AM
Oops. That code I posted is clearly nonsense but the edit button won't work. I think this should do it:
let N = root node
let S = empty stack
while N != null
Yield N
if n.hasRightChild
S.push N
if N.hasLeftChild
N = N.leftChild
else if S.isEmpty
N = null
else
N = S.pop.rightChild
Page 1 of 1
|
|



3 Comments








|