如何在Haskell中删除树的根

时间:2014-02-04 21:12:46

标签: haskell

我有一个二叉树。如何删除树的顶部(根)?我有一个名为treeTop的函数,它返回树的顶部,但是如何删除它? 那是我的树:

data Tree a = Empty
| Leaf a
| Node a (Tree a) (Tree a) String
deriving (Show)

1 个答案:

答案 0 :(得分:2)

假设这不是一棵平衡树,那么

 deleteRoot :: Tree -> Maybe Tree
 deleteRoot (Node _ l r _) = Just $ append l r
 deleteRoot _            = Nothing

其中append占用树,并将其粘贴在另一个树的末尾,实现这一点是相当机械的

 append :: Tree -> Tree -> Tree
 append Empty r    = r
 append (Leaf a) r = <???>
 append (Node v l r s) r' = Node v l (append r r') s

现在问题是,当您尝试将Leaf x附加到r时,不清楚该怎么做。使用Empty我们只是抛弃了值,因为它没有有用的信息,但是Leaf。例如,您可以将Leaf提升为具有Node a Empty r ""的节点,但没有明确的值可以放入String。我会让你决定。

当树应该平衡时,这显然是无稽之谈,但如果不是,那么我们将转向

             foo
            /    \
        bar        baz
       /   \      /   \
      0     0     0    0

    bar
   /   \
  0    baz
      /   \
     0     0

其中0表示Empty。请注意,原始树未经修改,因此如果我们启动了GHCi

 Main*> let test = Node () (Node () Empty Empty "bar") (Node () Empty Empty "baz") "foo"
 Main*> deleteRoot test
   Node Empty (Node Empty Empty "baz") "bar"
 Main*> test
   Node (Node () Empty Empty "bar") (Node () Empty Empty "baz") "foo"

所以它不会修改旧文本,但这就是函数式语言的工作方式,而不是破坏旧数据,我们保留它并创建新的不可变值。

我的最终代码最终为

data Tree a = Empty
            | Leaf a
            | Node a (Tree a) (Tree a) String
            deriving (Show)

deleteRoot :: Tree a -> Maybe (Tree a)
deleteRoot (Node _ l r _) = Just $ append l r
deleteRoot _            = Nothing

append :: Tree a -> Tree a -> Tree a
append Empty r = r
append (Leaf a) r  = Node a Empty r ""
append (Node v l r s) r' = Node v l (append r r') s