DFS在Haskell中的实现

DFS在Haskell中的实现,haskell,depth-first-search,Haskell,Depth First Search,我已经绞尽脑汁几个小时了,因为我不知道如何用Haskell编写DFS 我的图作为邻接列表实现,其中键(或图的节点名称)是列表索引: 0 -> 1 1 -> 0, 2 2 -> 1 As a Haskell list: [[1],[0,2],[1]] 以下是我到目前为止的DFS代码: dfs graph visited node = helper graph visited (graph !! node) node where helper _ _ visited [

我已经绞尽脑汁几个小时了,因为我不知道如何用Haskell编写DFS

我的图作为邻接列表实现,其中键(或图的节点名称)是列表索引:

0 -> 1
1 -> 0, 2
2 -> 1

As a Haskell list: [[1],[0,2],[1]]
以下是我到目前为止的DFS代码:

dfs graph visited node = helper graph visited (graph !! node) node
    where helper _ _ visited [] _ = visited
          helper graph visited (x:xs) currNode
            | elem x visited = helper graph visited xs currNode
            | otherwise = dfs graph (currNode:visited) x

我理解问题在于,一旦到达图形的一端,它不会回溯并尝试另一个相邻节点。我一直在试图修改防护的其他部分,试图修复它,但似乎无法想出一些有效的方法。我能做些什么来解决这个问题?

我还不太清楚你想做什么。我写了一些与你类似的东西,尽管它有与
相同的问题不是O(1),但它仍然是dfs

mydfs graph visited [] = reverse visited
mydfs graph visited (x:xs) | elem x visited = mydfs graph visited xs
                           | otherwise = mydfs graph (x:visited) ((graph !! x) ++ xs)
dfs回溯的想法是保留一个tobevisited列表,只需从中取出第一个条目并访问它,每当发现一个未访问的条目时,将其相邻顶点推到tobevisited列表的顶部


您可以使用数组或向量作为邻接列表来避免O(n)查找,但最好使用图形库来完成您要做的事情。

我能想到的最短路径

dfs current visited =
    foldl (\visited next -> if elem next visited then visited else dfs next visited)
           (visited ++ [current]) (graph !! current)
与python相比:

def dfs(v, visited):
    visited.append(v)
    for u in graph[v]:
        if u not in visited:
            visited = dfs(u, visited)
    return visited

那还可以编译吗?还有
的复杂性
在最坏的情况下为O(n),因此dfs的复杂性将大得多。如果这不是家庭作业,您可能需要使用函数图库(fgl)。它看起来让人望而生畏,拥有大量的模块,但实际上很容易使用。这对于答案来说太少了,但看看这篇文章:“在Haskell中构造深度优先搜索算法”www.researchgate.net/publication/2252048_Structuring_Depth-First_Search_Algorithms_in_Haskell/file/50463523c7a64b12d4.pdf–这不是最容易掌握的,但……好吧,应该表现良好。我稍后会做测试。