基于两个列表生成树

时间:2017-09-07 03:36:53

标签: haskell tree

我想知道如何基于两个列表生成树。第一个表示预订,第二个表示要生成的有序树中的一个,例如:

data Tree a = Branch a (Tree a) (Tree a) | Leaf deriving Show
genTree :: [a] -> [a] -> Tree a
genTree [7,9,2] [9,7,2] = 
Branch 7 (Branch 9 Leaf Leaf ) (Branch 2 Leaf Leaf )

接受任何建议,谢谢!!

1 个答案:

答案 0 :(得分:4)

中的

描述了序列中 root 位置。所以:

  1. inorder序列的第一个元素是 root 。然后离开子树顺序序列,然后是右子树。但我们不知道正确的子树序列从哪里开始。
  2. 如果我们可以在preorder序列中找到 root ,那么左侧是左子树的预序序列,右侧是右子树的预序序列。
  3. 假设我们有这样的二叉树:

      1
     / \
    2   3
       /  \
      4    5
    
    preorder: 1 2 3 4 5
    inorder : 2 1 4 3 5
    

    让我们重建它!好的,看看预订序列1 2 3 4 5。我们知道1是根。

    [1] 2 3 4 5
    2 [1] 4 3 5
    

    2是子树的顺序序列。 4 3 5是正确的子树。我们也知道:

    1. 左子树只有 1 节点,右边有 3 节点!
    2. 左边的子树预编码序列除了右边的预编码序列是2 3 4 5
    3. 因此,左前排是2,右边是3 4 5

      递归开始了。直到我们什么都没有!那是空的序列。然后我们遇到了Leaf

      总结起来,我们有以下Haskell代码。 (这不能处理错误的输入情况)

      data Tree a = Branch a (Tree a) (Tree a)
                  | Leaf
                  deriving Show
      --                 pre    in
      genTree :: Eq a => [a] -> [a] -> Tree a
      genTree [] [] = Leaf
      genTree (root:pre_seq) in_seq = Branch root left right
        where
          (left_in, _:right_in) = break   (== root)        in_seq
          (left_pre, right_pre) = splitAt (length left_in) pre_seq
          left  = genTree left_pre  left_in
          right = genTree right_pre right_in