在二叉树中查找元素

时间:2013-01-07 14:24:51

标签: search haskell tree find binary-tree

假设我有一个二叉树:

data Bst a = Empty | Node (Bst a) a (Bst a)

我必须编写一个搜索值并返回其子项数的函数。如果没有具有此值的节点,则返回-1。我试图写BFS和DFS,但两者都失败了。

2 个答案:

答案 0 :(得分:2)

模式匹配是你的朋友。您的Bst可以是EmptyNode,因此在顶层,您的search功能将

search Empty = ...
search (Node left x right) = ...

Empty树可能包含目标值吗?使用Node目标值(如果存在)将是x子树中的left子树中的节点值(right以上),或者可能是某些这些的组合。

通过“返回其子项的数量”,我假设您的意思是Bst的后代总数,其中NodenumChildren为根,其值为目标,这是一个有趣的问题的组合。您将需要另一个函数,例如Empty,其定义使用上述模式匹配。考虑:

  1. Node树有多少个后代?
  2. x案例中,left不计算在内,因为您需要后代。如果您只有一个函数来计算right和{{1}}子树中的子项数...

答案 1 :(得分:1)

这是一种方法。呼吸优先搜索实际上实现起来有点棘手,这个解决方案(findBFS)具有很高的复杂性(附加到列表中的是O(n)),但是你会得到要点。

首先,我决定拆分查找函数以返回节点元素匹配的树。这简化了分割计数功能。此外,返回元素数量比后代数量更容易,如果找不到则返回-1,因此numDesc函数依赖于numElements函数。

data Tree a = Empty
            | Node a (Tree a) (Tree a)

numElements :: Tree a -> Int
numElements Empty        = 0
numElements (Node _ l r) = 1 + numElements l + numElements r

findDFS :: Eq a => a -> Tree a -> Tree a
findDFS _ Empty                         = Empty
findDFS x node@(Node y l r) | x == y    = node
                            | otherwise = case findDFS x l of 
                                            node'@(Node _ _ _) -> node'
                                            Empty              -> findDFS x r

findBFS :: Eq a => a -> [Tree a] -> Tree a                                                                
findBFS x []                              = Empty
findBFS x ((Empty):ts)                    = findBFS x ts
findBFS x (node@(Node y _ _):ts) | x == y = node
findBFS x ((Node _ l r):ts)               = findBFS x (ts ++ [l,r])

numDescDFS :: Eq a => a -> Tree a -> Int
numDescDFS x t = numElements (findDFS x t) - 1

numDescBFS :: Eq a => a -> Tree a -> Int
numDescBFS x t = numElements (findBFS x [t]) - 1