Haskell中树数据结构的邻接列表

Cod*_*ice 5 haskell

我在Haskell中定义了以下抽象数据类型:

data Trie = Leaf
          | Node [(Char, Trie)]
          deriving (Eq)
Run Code Online (Sandbox Code Playgroud)

Node类型是元素的列表(c, t),其中c,是从当前节点到边缘的标签t.

现在我要打印出树的邻接列表.具体来说,我需要每行打印一个边,其中边的格式为:

n1 n2 c

n1源,n2目标和c边缘的标签.

我可以用我的根节点打印边缘

instance Show Trie where
    show = show' 2 1
        where show' _ _ Leaf = ""
              show' next n1 (Node ts) = unlines $ zipWith (\n2 (c, _) ->
                                                           show n1 ++ " " ++ show n2 ++ " " ++ show c)
                                                    [next..] ts
Run Code Online (Sandbox Code Playgroud)

但现在我被困在如何以递归方式打印孩子们.特别是,如何为子节点编号?

use*_*038 5

标记节点非常简单,因为GHC将为您完成所有繁重的任务:

{-# LANGUAGE DeriveFunctor, DeriveFoldable, DeriveTraversable #-}

import qualified Data.Traversable as T
import qualified Data.Foldable as F 
import Control.Monad.State 

data Trie a = Leaf a | Node a [(Char, Trie a)] 
  deriving (Eq, Functor, F.Foldable, T.Traversable)

number :: Trie a -> Trie (a, Int)
number = flip evalState 1 . T.mapM (\x -> state $ \n -> ((x,n),n+1))
Run Code Online (Sandbox Code Playgroud)

至于打印trie,我担心我不太理解所需的输出.


Eri*_*ikR 4

我想出了这个解决方案:

import Data.List (foldl')

enum :: Int -> Trie -> ([(Int,Int,Char)],Int)
enum x Leaf = ([],x+1)
enum x (Node pairs)
  = let go (acc,y) (c,t) = (acc',y')
          where acc' = [(x,y,c)] ++ edges ++ acc
                (edges,y') = enum y t
    in foldl' go ([],x+1) pairs
Run Code Online (Sandbox Code Playgroud)

enum接受起始 id 和 aTrie并返回边列表和下一个可用 id。

-- some examples:

leafs xs = [ (c,Leaf) | c <- xs ]
t1 = Node $ leafs "XYZ"
t2 = Node [('W', t1)]
t3 = Node $ [('A',t2)] ++ leafs "BC"

enum 1 t1 -- ([(1,4,'Z'),(1,3,'Y'),(1,2,'X')],5)
enum 1 t2 -- ([(1,2,'W'),(2,5,'Z'),(2,4,'Y'),(2,3,'X')],6)
enum 1 t3 -- ([(1,8,'C'),(1,7,'B'),(1,2,'A'),(2,3,'W'),(3,6,'Z'),(3,5,'Y'),(3,4,'X')],9)
Run Code Online (Sandbox Code Playgroud)