In Lua, how to write an iterator for a binary tree. e.g. so I could do something like:
for node in tree:visit() do ... end
I've been trying but best I can do is to walks the tree, carrying around some function fun as a payload. e.g.
function klass(s, t) t={ako=s}; t.__index=t; return t end
NODE=klass"NODE"
function NODE.new(x,l,r) return setmetatable( {x=x, left=l, right=r},NODE) end
function NODE:visit(fun, lvl)
lvl=lvl or 0
fun(lvl,self)
for _,kid in pairs{self.left, self.right} do
if kid then kid:visit(fun, lvl+1) end end end
--- eg -----------------------------
function eg(x,stop, node)
node = NODE.new(x)
if x < stop/2 then
node.left = eg(2*x,stop)
node.right = eg(2*x+1,stop) end
return node end
tree=eg(1,32)
tree:visit( function(lvl,node) print(('|.. '):rep(lvl)..node.x) end )
This produces the output I want:
1
|.. 2
|.. |.. 4
|.. |.. |.. 8
|.. |.. |.. |.. 16
|.. |.. |.. |.. 17
|.. |.. |.. 9
|.. |.. |.. |.. 18
|.. |.. |.. |.. 19
|.. |.. 5
|.. |.. |.. 10
|.. |.. |.. |.. 20
|.. |.. |.. |.. 21
|.. |.. |.. 11
|.. |.. |.. |.. 22
|.. |.. |.. |.. 23
|.. 3
|.. |.. 6
|.. |.. |.. 12
|.. |.. |.. |.. 24
|.. |.. |.. |.. 25
|.. |.. |.. 13
|.. |.. |.. |.. 26
|.. |.. |.. |.. 27
|.. |.. 7
|.. |.. |.. 14
|.. |.. |.. |.. 28
|.. |.. |.. |.. 29
|.. |.. |.. 15
|.. |.. |.. |.. 30
|.. |.. |.. |.. 31
But how do I write this such that I can work it into a for loop?
There are two solutions I'd like to avoid:
- I don't want to use
pairsto over a list of nodes generated via the my code above (since I'd like to support incremental traversal of trees of arbitrary depth) - I want the answer to be (much) less complex than https://github.com/guicaulada/lua-bintrees/blob/main/bintrees/iterator.lua
If you need to convert a recursive function into a loop, then you need a stack to simulate the call stack during recursion.
The for-in statement in lua needs 3 values: an iterator function, a state (the stack here), an initial value (omitted here):
And the usage: