General Transformation
- for each of the parameters that might change values in a recursive call,
- for all the local variables (unless they are declared as static),
- for any marks used to store the place in the function where we return after a recursive call was made.
Transformation
One Recursive Call
The stack stores the values of n. The variable r stores the result of
the recursive function call.
(defun factorial1 (n)
(let ((st ()) (r 1))
(push n st)
(while st
(cond
((>= n 2)
(setq n (- n 1))
(push n st))
(t (setq r (* r (pop st))))))
r))
Second Example
f(n) = 2 n2 + 3 f(n-1), f(1) = 2
(defun f (n)
(if (= n 1) 2
(+ (* 2 n n)
(* 3 (f (- n 1))))))
Iterative Version
Just like before, the stack stores n, while r is the result of the
recursive call. Once we reach the base case and we start coming back
up, we need a local variable to store the copy of n as we pop it from
the stack, because the test for having reached the base case depends
on it.
(defun f (n)
(let ((st ()) (r 2) (ln 0))
(push n st)
(while st
(cond
((> n 2)
(setq n (- n 1))
(push n st))
(t (setq ln (pop st))
(setq r (+ (* 2 ln ln)
(* 3 r))))))
r))
Tree
(23 (51 (18)
(33 (5) ))
(7 () (10)))
Tree Structure
(defun root (T) "The root of the tree."
(if T (car T)))
(defun left-subtree (T)
"The left subtree, also a list."
(if (and T (cdr T))
(car (cdr T)))) ; (cadr T)
(defun right-subtree (T)
"The right subtree, also a list."
(if (> (length T) 2)
(car (cdr (cdr T))))) ; (caddr T)
Print in Pre-Order
(defun print-preorder (T)
"Prints the tree in preorder. Root - L - R"
(if T
(progn
(mapc 'princ (list (root T) " "))
(print-preorder (left-subtree T))
(print-preorder (right-subtree T)))))
(setq S '(23 (51 (18) (33 (5))) (7 () (10))))
(print-preorder S)
23 51 18 33 5 7 10 nil
States
Iteration
(defun print-preor (T)
"Prints the list in preorder without recursion."
(let ((stackT nil) (frame nil)
(state nil))
(push (cons T 'root) stackT)
(while stackT
(setq frame (pop stackT))
(setq T (car frame) state (cdr frame))
(if T
(cond ((eq state 'root)
(my-print (root T) " ")
(push (cons T 'left) stackT))
((eq state 'left)
(push (cons T 'right) stackT)
(push (cons (left-subtree T)
'root) stackT))
((eq state 'right)
(push (cons (right-subtree T)
'root) stackT)))))))
Optimization
(defun print-preord (T)
"An optimization of the function above."
(let ((stackT ()))
(while T
(my-print (root T) " ")
(push T stackT)
(setq T (left-subtree T)))
(while stackT
(setq T (pop stackT))
(setq T (right-subtree T))
(while T
(my-print (root T) " ")
(push T stackT)
(setq T (left-subtree T))))))