haskell - 从树中删除一个节点并返回结果森林

标签 haskell tree

我有 Java 背景,想学习一些 Haskell。不过目前有点卡住了。

我想要做的是:我有一个树列表,其中每个节点在列表中的所有树中都有唯一的标识符。现在我想从这些树之一中删除一个节点并返回新树以及未更改的树。

删除节点应该:

  • 使该节点的所有子节点成为新树的根
  • 删除已删除节点的父节点,直到根节点(包括根节点),并对所有已删除节点执行上述操作

想象一下以下树:

enter image description here

当我删除节点“2”时,我希望结果是以下树:

enter image description here

树中的每个节点都由标识符和子树列表组成。 这是我到目前为止所拥有的,但它显然不起作用,而且我对如何用 Haskell 解决这个问题有点迷失:

import Data.Tree
data CustomNode = CustomNode { identifier :: Int } deriving (Ord,Eq,Show,Read)
type CustomTree = Tree CustomNode

myTree0 = t0
    where
        leaf i = Node CustomNode{identifier = i} []
        t0 = Node CustomNode{identifier = 0} [t1]
        t1 = Node CustomNode{identifier = 1} [t2, t5]
        t2 = Node CustomNode{identifier = 2} [leaf 3, leaf 4] 
        t5 = Node CustomNode{identifier = 5} [leaf 6]

myTree1 = t0
    where
        leaf i = Node CustomNode{identifier = i} []
        t0 = Node CustomNode{identifier = 7} [leaf 8]

deleteNode :: Int -> [CustomTree] -> [CustomTree]
deleteNode _ [] = []
deleteNode n (x:xs) = if isNodeInTree n x then deleteNodeFromTree n x ++ xs else deleteNode n xs
--below is the fixed line as per the answer below
--deleteNode n (x:xs) = if isNodeInTree n x then deleteNodeFromTree n x ++ xs else x : deleteNode n xs

deleteNodeFromTree :: Int -> CustomTree -> [CustomTree]
deleteNodeFromTree n (Node c xs) = if identifier c == n then [] else deleteNode n xs
--below is the fixed line as per the answer below
--deleteNodeFromTree n (Node c xs) = if identifier c == n then xs else deleteNode n xs

isNodeInTree :: Int -> CustomTree -> Bool
isNodeInTree n (Node c xs) = if identifier c == n then True else isNodeInForest n xs

isNodeInForest :: Int -> [CustomTree] -> Bool
isNodeInForest n [] = False
isNodeInForest n (x:xs) = if isNodeInTree n x then True else isNodeInForest n xs

任何帮助将不胜感激!

最佳答案

看起来您已经有了一个合理的开始。

我假设您希望 deleteNode 获取一个森林并返回同一森林,但删除了指定的节点。在这种情况下,

if isNodeInTree n x then ... else deleteNode n xs

你刚刚扔掉了x。你可能不是故意的。

... else x : deleteNode n xs

将那棵树保留在森林中,这可能就是您的意图。

此外,在deleteNodeFromTree中:

if identifier c == n then [] ...

也许此时您想返回该节点的所有子节点? (所以它们都成为根节点。)

这些是对我来说唯一突出的事情。看看它会带你去哪里......

关于haskell - 从树中删除一个节点并返回结果森林,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27602281/

相关文章:

haskell - 带递归的 Monad Transformer

c# - 基于子项或父项的树结构

python - 从大型 JSON 文件创建树状结构的最有效方法

haskell - 为什么 ParsecT 类型有 'u' 参数?

haskell - 限制效果,例如 `Freer` ,使用 MTL 样式

haskell - 在haskell中实现选择2个以上的镜头

Haskell "Couldn' t 将预期类型 ‘a’ 与实际类型 ‘[a0]’ 匹配“

php - 从 PHP Mysql 标签的逗号分隔值中搜索关键字

python - 如何在Python中绘制这个树形图案?

java - 明智地打印树级别