[英]Leftmost value in a tree (Haskell)
如何找到树中最左边的值? 最左端是通过尽可能长时间移到当前节点的左子节点而获得的值。
树类型定义为:
data Tree a = Leaf | Node a (Tree a) (Tree a) deriving (Show, Eq)
我目前有以下内容:
leftest :: Tree a -> Maybe a
leftest (Leaf) = Nothing
leftest
应返回的示例:
最左边的(节点1(节点2(节点3叶子叶子)叶子)叶子)->仅3
最左(节点1(节点2叶子(节点3叶子))(节点4叶子))->仅2
在用Haskell编写函数之前 ,最好先考虑一下树中最左侧元素的(归纳)定义。
您实际上已经写了其中一部分:
leftest (Leaf) = Nothing
在这里,您基本上声明:“ 一片叶子没有最左边的元素 ”。 所以现在的问题是, Tree a (Tree a) (Tree a)
的最左值是多少?
我们可以在这里推断几种情况。 这里基本上有四种情况:两个子树可以是Leaf
或Tree ...
s,对于每种情况,我们都可以尝试提出一个解决方案:
Tree x Leaf Leaf
,因此这里有一个没有任何子节点的节点(实际上,在大多数有关数据结构的书中都是叶子 ),在这种情况下,最左边的值是Tree x Leaf Leaf
携带的值。 x
,所以我们可以返回Just x
; Tree x Leaf (Tree _ _ _)
,这里有一棵树,右边只有一个孩子。 由于那个孩子及其所有后代都在右边,因此我们可以再次返回该节点的元素,所以Just x
; Tree x (Tree _ _ _) Leaf
,这里我们只有一个孩子。 在这种情况下,该树的最左侧与左子节点的最左端相同,因此我们对左子节点进行递归; 和 Tree x (Tree _ _ _) (Tree _ _ _)
,这里的节点有两个子节点,但是就像我们已经争论过的那样,右子节点并不重要,我们可以再次对左子节点进行递归。 所以我们可以这样写:
leftmost :: Tree a -> Maybe a
leftmost Leaf = Nothing
leftmost (Tree x Leaf Leaf) = Just x -- (1)
leftmost (Tree x Leaf (Tree _ _ _)) = Just x -- (2)
leftmost (Tree x c@(Tree _ _ _) Leaf) = leftmost c -- (3)
leftmost (Tree x c@(Tree _ _ _) (Tree _ _ _)) = leftmost c -- (4)
这实际上有效,但相当冗长:既然合适的孩子并不重要,为什么我们要考虑四种情况? 我们可以将这种情况限制为两种情况:
leftmost :: Tree a -> Maybe a
leftmost Leaf = Nothing
leftmost (Tree x Leaf _) = Just x -- (1+2)
leftmost (Tree x c@(Tree _ _ _) _) = leftmost c -- (3+4)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.