所以问题很简单。给定一个图形(我希望图形的结构在这个问题上没有多大关系),我该怎么做呢?
我最近问过一个关于生成列表的问题,其中每个元素都会在其末尾添加许多元素。答案应该有希望让我做一个我需要做BFS的队列。但是搜索需要另一个关键组件,它将节点标记为已访问,因此我们不会再次检查它们。这也需要在算法的执行上没有开销。无论是标记还是阅读。
由于Haskell不让我改变状态,我该如何去做呢?
(我不是在寻找将我的命令式代码翻译成Haskell的方法。惯用的Haskell解决方案会很棒。)
答案 0 :(得分:7)
正如评论中所提到的,正确的方法是将图表与标记其节点分开。您需要使用某种集合容器。您基本上可以采取两种方法:
答案 1 :(得分:6)
论文Inductive Graphs and Functional Graph Algorithms讨论了这些问题并且非常易读。它是fgl包的基础,具有an entire module for BFS-like queries。我强烈推荐这篇论文 - 这对我来说是一个令人大开眼界的读物(即,即使你的数据不是归纳的,“给出一个感应界面的基本核心思想是一个很棒的”) - 并进一步建议如果你可以使用你做的fgl包。但是,如果你不能,那么本文将告诉你足够为自定义数据类型编写算法,我敢肯定。
答案 2 :(得分:0)
我认为,最简单的方法是查看树形图中的任何级别。
现在很容易翻译,(这段代码首先使图表变宽)。
toBFSList :: [Graph a] -> [Graph a]
toBFSList [] = [] -- trivial case
toBFSList gs = ns ++ fs
where ns = map extract gs -- "extract" may extract a single node
cs = concat $ map children gs -- get all the child nodes for all above node
fs = toBFSList cs -- for all children, do traversal