evelyn baesa <
evely...@gmail.com> writes:
> How can LISP be used in back-tracking in a tree ?
Your problem statement is underspecified.
Backtracking is a notion that applies to a walking algorithm.
There are a lot of different ways to walk a tree.
In away, a walk of a tree that starts from the root and visits all the
nodes going thru their parent-child connections, is characterized
naturally by backtracking: after having visited a subtree, you
"backtrack" to the current node to visit the following subtree.
So for example:
(defstruct node
label left right)
(defun postfix-walk (node visit)
(when (node-left node)
(postfix-walk (node-left node) visit))
#|backtrack|#
(when (node-right node)
(postfix-walk (node-right node) visit))
#|backtrack|#
(funcall visit node))
(postfix-walk (make-node :label 'root
:left (make-node :label 'left
:left (make-node :label 'left-left)
:right (make-node :label 'left-right))
:right (make-node :label 'right))
(lambda (node) (print (node-label node))))
prints:
left-left
left-right
left
right
root
and you can see how the algorithm in postfix-walk "backtracked" from the
left-left node to visit the left-right node, and then backtracked twice
to visit the right node. Another way to make it even more obvious, use
the TRACE CL operator:
cl-user> (trace postfix-walk)
nil
cl-user> (postfix-walk (make-node :label 'root
:left (make-node :label 'left
:left (make-node :label 'left-left)
:right (make-node :label 'left-right))
:right (make-node :label 'right))
'identity)
0> Calling (postfix-walk #S(node :label root :left #S(node :label left :left #S(node :label left-left :left nil :right nil) :right #S(node :label left-right :left nil :right nil)) :right #S(node :label right :left nil :right nil)) identity)
1> Calling (postfix-walk #S(node :label left :left #S(node :label left-left :left nil :right nil) :right #S(node :label left-right :left nil :right nil)) identity)
2> Calling (postfix-walk #S(node :label left-left :left nil :right nil) identity)
<2 postfix-walk returned #S(node :label left-left :left nil :right nil)
2> Calling (postfix-walk #S(node :label left-right :left nil :right nil) identity)
<2 postfix-walk returned #S(node :label left-right :left nil :right nil)
<1 postfix-walk returned #S(node :label left :left #S(node :label left-left :left nil :right nil) :right #S(node :label left-right :left nil :right nil))
1> Calling (postfix-walk #S(node :label right :left nil :right nil) identity)
<1 postfix-walk returned #S(node :label right :left nil :right nil)
<0 postfix-walk returned #S(node :label root :left #S(node :label left :left #S(node :label left-left :left nil :right nil) :right #S(node :label left-right :left nil :right nil)) :right #S(node :label right :left nil :right nil))
you can see how the recursive algorithm backtracks from recursive calls
to continue processing the other parts of the tree.
--
__Pascal Bourguignon__
http://www.informatimago.com/
A bad day in () is better than a good day in {}.
You can take the lisper out of the lisp job, but you can't take the lisp out
of the lisper (; -- antifuchs