我正在试着弄清楚如何在方案中实现广度优先树遍历。我用Java和C ++完成了它。如果我有代码,我会发布它,但我不确定如何开始。
鉴于下面的树定义,如何使用递归实现广度优先搜索?
(define tree1 '( A ( B (C () ()) (D () ()) ) (E (F () ()) (G () ())) ))
答案 0 :(得分:2)
我敢打赌当你用其他语言执行此操作时,你使用了dfs的堆栈和bfs的队列。当您进行深度优先搜索时,您基本上使用堆栈来决定下一个要探索的节点,并且递归会为您提供一个函数调用堆栈,因此很容易将两者如何相互镜像。通过广度优先搜索,问题就变成了,如何递归遍历队列?
现在回想一下,你可以迭代地做任何事情,你可以递归地做。您可以写“当x< 10:x + = 1”时,您可以写
(define (my-loop x)
(if (< x 10)
(my-loop (+ x 1))
... ;; your base case
))
然后突然你以递归方式进行迭代。大。
所以我们有这个队列。我们把事情放在一边,把事情从另一端拿走。就像我们在上面的循环中传递循环控制变量x一样,你必须明确地传递队列。在下一个“迭代”中,现在变为下一个递归级别,您将希望在队列中放置一些新子节点,并且下一次递归将使一个子节点离队列的另一端,或者停止(返回) )如果没有更多的孩子。
现在调用堆栈不再镜像树中的位置,因此很难看出为什么递归会更好或更直观,但它始终是可能的。
希望有所帮助,
GREM
答案 1 :(得分:1)
0)这是家庭作业吗?如果是这样,请停止阅读:)。
BFS算法:如果队列为空,请放弃。否则,将队列分成第一个并保留,检查第一个是否是您想要的队列,否则重复使用包含剩余元素和所有新可到达队列的队列。
当然,我可以在Scheme中“说”同一句话:
#lang scheme (define (bfs pred queue) (match queue [empty #f] [(cons elt queue-rest) (or (pred elt) (bfs pred (append queue-rest (remove* queue-rest (reachable-from elt)))))]))
1)完全未经测试,几乎肯定是错误的(尽管不是在测量理论意义上:))
2)你需要自己的图表和图形表示。 “可达-从”
3)列表不是一个很好的队列实现。
答案 2 :(得分:0)
(defun findAtN (tree n)
(cond ((equal tree nil) nil)
((equal (n 0) (car tree))
(t (append (findAtN (cadr tree) (- n 1))
(findAtN (caddr tree) (- n 1))))))
然后是第二个增加深度的函数,搜索给定节点的每个级别。
(defun ContainsElt (tree Elt n)
(cond ((equal (findAtN tree n) nil) nil)
((member Elt (findAtN tree n)) true)
(t (ContainsElt tree Elt (+ n 1)))))
这是未经测试的,可能会根据您的lisp参数/方言略有不同,以及如果您想要做的不仅仅是测试一个项目是否在树中,但也许它有助于一个想法如何做到这一点。