Сер*_*кий 7 recursion binary-tree haskell fold higher-order-functions
我编写了foldTree从列表构建平衡二叉树的函数.我必须使用foldr,它没关系,我使用它,但我使insertInTree函数递归=(现在我只知道这种方式穿过树=)).
更新:我不确定功能insertTree:是否正确计算递归的高度?=((这里需要一些帮助.
是否可以在insertInTree没有递归的情况下编写(使用某些东西until/iterate/unfoldr)或者在foldTree没有辅助函数的情况下编写函数=>以某种方式缩短?
这是我的尝试如下:
data Tree a = Leaf
| Node Integer (Tree a) a (Tree a)
deriving (Show, Eq)
foldTree :: [a] -> Tree a
foldTree = foldr (\x tree -> insertInTree x tree) Leaf
insertInTree :: a -> Tree a -> Tree a
insertInTree x Leaf = Node 0 (Leaf) x (Leaf)
insertInTree x (Node n t1 val t2) = if h1 < h2
then Node (h2+1) (insertInTree x t1) val t2
else Node (h1+1) t1 val (insertInTree x t2)
where h1 = heightTree t1
h2 = heightTree t2
heightTree :: Tree a -> Integer
heightTree Leaf = 0
heightTree (Node n t1 val t2) = n
Run Code Online (Sandbox Code Playgroud)
输出:
*Main> foldTree "ABCDEFGHIJ"
Node 3 (Node 2 (Node 0 Leaf 'B' Leaf) 'G' (Node 1 Leaf 'F' (Node 0 Leaf 'C' Leaf))) 'J' (Node 2 (Node 1 Leaf 'D' (Node 0 Leaf 'A' Leaf)) 'I' (Node 1 Leaf 'H' (Node 0 Leaf 'E' Leaf)))
*Main>
Run Code Online (Sandbox Code Playgroud)
当两个子树的高度相等时,您的插入函数会出错,因为如果右子树已经满了,则插入到右子树中会增加其高度。我不清楚您的代码中是否会出现这种情况。
将新元素插入树中的明显正确方法似乎是
insertInTree x (Node n t1 val t2)
| h1 < h2 = Node n (insertInTree x t1) val t2
| h1 > h2 = Node n t1 val t2n
| otherwise = Node (h+1) t1 val t2n
where h1 = heightTree t1
h2 = heightTree t2
t2n = insertInTree x t2
h = heightTree t2n -- might stay the same
Run Code Online (Sandbox Code Playgroud)
这会创建几乎平衡的树(又名 AVL 树)。但它将每个新元素推到树的最底部。
编辑:这些树可以很好地看到
showTree Leaf = ""
showTree n@(Node i _ _ _) = go i n
where
go _ (Leaf) = ""
go i (Node _ l c r) = go (i-1) l ++
replicate (4*fromIntegral i) ' ' ++ show c ++ "\n" ++ go (i-1) r
Run Code Online (Sandbox Code Playgroud)
尝试
putStr 。showTree $ FoldTree "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
是的,你可以写得foldTree更短,比如
foldTree = foldr insertInTree Leaf
Run Code Online (Sandbox Code Playgroud)