我正在尝试编写一个程序,它将在树中找到元素并返回树中有多少元素<我的元素。
data Bst a = Empty | Node (Bst a) a (Bst a)
lElems :: Ord a => a -> Bst a -> Int
lElems n t = (counto (findEl n 0 0 t) t)
counto :: Ord a => a -> Bst a -> Int
counto n Empty = 0
counto n (Node l m r)
| m == n = counto n l
| n > m = 1 + (counto n l) + (counto n r)
| n < m = counto n l
findEl:: Ord a => a -> a -> a -> Bst a -> a
findEl n anc sta Empty = anc
findEl n anc sta (Node l m r)
| m == n = anc
| n > m = if anc == sta || anc > m then findEl n m sta r else findEl n anc sta r
| n < m = if anc > m || anc == sta then findEl n m sta l else findEl n anc sta r
counto
和findEl
效果很好,但是当我尝试一起使用它时,我有这个错误
这是我的测试树
lElems 2 (Node (Node (Node Empty 1 (Node Empty 2 Empty)) 3 (Node Empty 5 (Node Empty 4 Empty))) 6 (Node (Node Empty 7 Empty) 8 (Node Empty 9 Empty)))
我想不改变data Bst
定义
那么,为什么a
不能成为整数?在lElems
中出了什么问题?
||| ||| EDIT
首先0是0,如果树中没有这样的元素,将返回0。 第二个0是0与0相比,它只是findEl在我的计算机上工作的一种方式
但是,如果我将零更改为变量p
和m
,并使用零lElems
调用lElems 2 0 0 tree
则可以使用
答案 0 :(得分:1)
如果您使用其包含的元素数量来扩充每个子树,
data BinaryTree a = Empty | Node a Integer (BinaryTree a) (BinaryTree a)
insert :: Ord a => a -> BinaryTree a -> BinaryTree a
insert x Empty = Node x 1 Empty Empty
insert x (Node y n left right) =
case x `compare` y of
LT -> Node y (n+1) (insert x left) right
GT -> Node y (n+1) left (insert x right)
EQ -> Node y n left right
numElems :: BinaryTree a -> Integer
numElems Empty = 0
numElems (Node _ n _ _) = n
然后更容易找到小于元素的元素数(忽略重复):
countLT :: Ord a => a -> BinaryTree a -> Integer
countLT x Empty = 0
countLT x (Node y n left right) =
case x `compare` y of
LT -> countLT x left
GT -> 1 + numElems left + countLT x right
EQ -> numElems left
E.g。
ghci> let t = insert 43 (insert 41 (insert 42 Empty))
ghci> map (\i -> countLT i t) [41,42,43,44]
[0,1,2,3]