从特定列表构建树

时间:2015-04-09 08:14:05

标签: haskell

从列表构建树的最佳方法是什么?我有兴趣找到解决这个问题的功能方法。哪些软件包和模块可以提供帮助?

这个问题是关于将初始结构存储到树中,而不仅仅是将其显示为树。

初始结构:

[[1, 1, 1, 0.5],
 [1, 1, 2, 0.5],
 [1, 1, 3, 0.5],
 [1, 1, 4, 0.5],
 [1, 1, 5, 0.5],
 [1, 2, 1, 0.5],
 [1, 2, 2, 0.5],
 [1, 2, 3, 0.5],
 [1, 2, 4, 0.5],
 [1, 2, 5, 0.5]]

结果(用手打字):

Node 1
    Node 1
        Node 1
            Node 0.5
        Node 2
            Node 0.5
        Node 3
            Node 0.5
        Node 4
            Node 0.5
        Node 5
            Node 0.5
    Node 2
        Node 1
            Node 0.5
        Node 2
            Node 0.5
        Node 3
            Node 0.5
        Node 4
            Node 0.5
        Node 5
            Node 0.5

谢谢!

2 个答案:

答案 0 :(得分:4)

定义一些树结构

data T a = T a [T a] deriving Show

并将每一行插入

insert :: Eq a => [T a] -> [a] -> [T a]
insert ts [] = ts
insert [] (x:xs) = [T x $ insert [] xs]
insert (t@(T n ns):ts) xss@(x:xs)
    | n == x    = (T n (insert ns xs)):ts
    | otherwise = t: insert ts xss

许多行到树

fromList :: Eq a => [[a]] -> [T a]
fromList = foldl insert []

打印

showTree :: Show a => [T a] -> [String]
showTree ts = concat [ ("Node " ++ show n): map ("  "++) (showTree ns) | T n ns <- ts]

例如

main = do
    putStrLn $ unlines $ showTree  $ fromList
        [[1, 1, 1, 0.5],
         [1, 1, 2, 0.5],
         [1, 1, 3, 0.5],
         [1, 1, 4, 0.5],
         [1, 1, 5, 0.5],
         [1, 2, 1, 0.5],
         [1, 2, 2, 0.5],
         [1, 2, 3, 0.5],
         [1, 2, 4, 0.5],
         [1, 2, 5, 0.5]]
所得

Node 1.0
  Node 1.0
    Node 1.0
      Node 0.5
    Node 2.0
      Node 0.5
    Node 3.0
      Node 0.5
    Node 4.0
      Node 0.5
    Node 5.0
      Node 0.5
  Node 2.0
    Node 1.0
      Node 0.5
    Node 2.0
      Node 0.5
    Node 3.0
      Node 0.5
    Node 4.0
      Node 0.5
    Node 5.0
      Node 0.5

答案 1 :(得分:3)

这有时被称为玫瑰树,来自容器包(GHC附带)的Data.Tree提供了一个类型定义和一些工具来处理这些(非常简单,但因为你已经拥有它们了......)。

您可以通过重复插入每个路径来完成这项工作,但这不会利用列表的结构。如果你保证它已被排序,你可以直接生成树(或者更确切地说是森林,因为不能保证所有子列表具有相同的头部),通过类似的头将子列表分组,然后递归地从尾部生成子林:

fromSortedList :: (Eq a) => [[a]] -> Forest a
fromSortedList [] = []
fromSortedList xs = concatMap fromOneGroup . groupBy eq $ xs
  where
    eq (x:_) (y:_) = x == y
    eq _     _     = False
    fromOneGroup ([] : _) = []
    fromOneGroup xs       = [Node (head . head $ xs) (fromSortedList . map tail $ xs)]

你应该对此进行基准测试,以确定它比重复插入更快。