【发布时间】:2017-02-25 04:14:01
【问题描述】:
我正在尝试使用递归算法构造 DFS 树。
这个伪代码是:
DFF(G)
Mark all nodes u as unvisited
while there is an unvisited node u do
DFS(u)
.
DFS(u)
Mark u as visited
for each v in u's neighbor do
if v is not marked
DFS(v)
虽然我可以通过为未访问/访问过的节点构造某种数据结构,为它们分配动态分配或某种声明,以简单的方式用命令式语言轻松完成此任务,但对于 Haskell 来说,这是不可能的,因为 Haskell 的纯粹性阻止我在传递参数时更改数据。
data Graph a = Graph [(a,[a])] deriving (Ord, Eq, Show)
data Tree a = Node a [Tree a] deriving (Ord, Eq, Show)
type Point = (Int, Int)
type Edges = [Point]
type Path = [Point]
pathGraphFy :: Graph Point -> Point -> Tree (Point,Path)
pathGraphFy inputGraph point = getPathVertex inputGraph (point,[])
getPathVertex :: Graph Point -> (Point, Path) -> Tree (Point,Path)
getPathVertex inputGraph (point,path) =
Node (point,point:path) (map (getPathVertex inputGraph) [(x,(point:path)) | x<- neighbors, x `notElem` path])
where neighbors = pointNeighbor inputGraph point
pointNeighbor :: Graph Point -> Point -> Edges
pointNeighbor (Graph (x:xs)) point =
if fst x == point then snd x else pointNeighbor (Graph(xs)) point
这是我使用 DFS-ish(或者更确切地说是 BFS-ish)算法进行图遍历的结果,但问题是它将再次访问不在点路径中的所有点。 (即如果存在循环,它将顺时针和逆时针两种方式遍历)
我也尝试过使用访问点对另一个 Graph 进行柯里化,但失败了,因为通过参数传递的 Graphs 仅在遍历中保存 Graph 的数据(即不是全局的)
如果只有动态分配或静态数据来保存全局级别的数据是可能的,这可以很容易地解决,但我对 Haskell 有点陌生,我无法在网上找到关于这个问题的答案。请帮助我:(提前谢谢。
(附注) 我尝试使用传递访问节点列表,但它不起作用,因为当递归返回时,访问节点列表也会返回,从而无法跟踪数据。如果有办法使“地图”或“列表”全局化,则可以通过这种方式实现。尽管下面的答案是仅链接的答案,但对不能(或不应该)实施的原因有很好的解释。
【问题讨论】:
标签: algorithm haskell depth-first-search