August 21, 2024
P87 - Depth-first order graph traversal (alternative solution)
Write a function that generates a depth-first order graph traversal sequence. The starting point should be specified, and the output should be a list of nodes that are reachable from this starting point (in depth-first order).
lisp
;;; DFS
;;; Takes graphs in adjacency list form
;;; maintain as state:
;;; the graph,
;;; the traversal so far (in reverse order, for easy augmentation)
;;; the stack of lists of neighbors to see
;;; the current list of neighbors-to-see
;;;
;;; Using the abbreviation: neighbors-to-see = nts
(load "p84.lisp")
(defun dfs (graph node)
(dfs-aux graph (list node) nil (neighbors node graph))
)
(defun dfs-aux (graph traversal stack nts)
(cond
;; case 1: next neighbor to see has already been visited
((and nts (member (car nts) traversal))
;; just disregard this neighbor
(dfs-aux graph traversal stack (cdr nts)))
;; case 2: next neighbor to see not yet visited
(nts
;; pushd remaining list of neighbors to see, start a new one
(dfs-aux graph
(cons (car nts) traversal)
(cons (cdr nts) stack)
(neighbors (car nts) graph)))
;; case 3: no more neighbors to see, but stack not empty
(stack
;; pop a list of neighbors to see from stack
(dfs-aux graph traversal (cdr stack) (car stack)))
;; case 4: no more neighbors to see, empty stack
(t
;; return traversal; remember it is built reversed
(reverse traversal))
)
)