Sun 14 Oct 2007

Surprisingly elegant code

Late last night I wanted to wrap up binary tree traversal into a generator — that is, rather than having the control flow of the program be specified by the traversal, making a function that yields the next element from the tree each time it is called.

It turned out to be easier than I imagined, requiring only one newish operation: depth-first traversal of the left branch of a node, collecting onto a stack the elements thus traversed. I termed this “enstack-l”.

Assuming that your tree has a btree-root accessor, and that each node has node-l, node-r, and node-elt accessors, the Common Lisp code is simply

(defun btree-generator (btree)
(let ((stack (list)))
(labels ((enstack-l (bn)
(loop for b = bn then (node-l b)
while b do
(push b stack)))
(pop-and-process ()
(let ((bn (pop stack)))
(when bn
(enstack-l (node-r bn))
(node-elt bn)))))

(enstack-l (btree-root btree))

(lambda ()
(pop-and-process)))))

(If the btree itself is just its topmost element, as it would be for a simple cons tree, the function becomes even simpler.)

Isn't it nice when things are easier than you thought? That while inside the loop alone handles a couple of tests for null.

Posted at 2007-10-14 18:41:33 by RichardLink to Surprisingly elega…