在二叉树中查找值为x的叶子

时间:2012-11-11 11:07:46

标签: haskell tree binary-tree

我有这个问题要做:

“定义一个函数findpath:: BTree a -> a -> Path(其中Btree a在前面的问题中被定义),给定二叉树t和值x,返回一个从t的根到一个值为x的叶子(如果有的话),另一个值为Nothing。程序的运行时间应该是线性的树。“

到目前为止,我有:

data Maybe a = Nothing | Just a
data BTree a = Leaf a | Fork (BTree a) (BTree a)
type Path = Maybe [Dir]
data Dir = Left | Right

findpath :: Eq a => BTree a -> a -> Path
findpath (Leaf y) x = if y==x then ??? else Nothing
findpath (Fork l r) x = nodepath (findpath l x) (findpath r x) where
   nodepath :: Path -> Path -> Path
   nodepath Nothing Nothing = Nothing
   nodepath Nothing pathr = Just [R]
   nodepath pathl Nothing = Just [L]

我仍然无法在(Leaf y)案例

中构建最终答案

1 个答案:

答案 0 :(得分:13)

您的语言,关于您认为该计划应该做什么,向我建议您需要帮助才能摆脱强制性思维的陷阱。让我尝试提供一些帮助,基于对 的内容的思考,而不是做什么

对于findpath (Leaf y) x,您正朝着正确的方向前进。您只需要将if改为小写i,并考虑PathLeaf的正确位置。

现在,让我们考虑另一种可能性。你知道的不仅仅是t。你知道你真的想弄明白什么

findpath (Node l r) x

(确实是=),因为这是BTree的另一种可能性。考虑通过询问“这是BTree一个(Leaf y)还是(Node l r)来解决问题?”作为程序设计的一个概念步骤。现在,为了弄清楚上面的左边是什么,你有权获得一些递归计算的信息,即什么

findpath l x

findpath r x

是。如果您知道Pathl的{​​{1}}信息,您能说出整个r的{​​{1}}是什么吗?让我在Haskell中写一下这个问题:

Path

我通过引入辅助函数 Node l r表达了我的问题,该函数将递归计算的信息作为参数。现在,您可以尝试分别通过左右子树的这两个路径上的模式匹配来实现findpath :: Eq a => BTree a -> a -> Path findpath (Leaf y) x = if y==x then ??? else Nothing findpath (Node l r) x = nodepath (findpath l x) (findpath r x) where nodepath :: Path -> Path -> Path nodepath ??? 。如果您知道它们是nodepath还是nodepath,那么您应该能够说明整个节点的路径必须是什么。

第一课,有用的想法是这样的形式:“如果这就像这样,那么那必定是某某。”存在,不做。

第二课,对数据类型进行编程的基本方法是:拆分为构造函数案例((Just p)NothingLeafNode);通过递归调用从任何子结构中收集有用的信息;说出整个结构的价值必须是什么。

如果您遵循我的建议并找出Just应该是什么,您可能会发现它很简单,不值得单独命名。在这种情况下,只需将Nothing调用替换为其含义,并删除nodepath - 子句。但最好先介绍nodepath,因为它表达了解决问题的有用概念步骤。