【发布时间】:2011-02-21 04:12:11
【问题描述】:
除了递归调用左右子树上的 size 函数之外,还有什么方法可以测试二叉树是否平衡。 abs(size left - size right)
【问题讨论】:
-
你的二叉树是如何表示的?
标签: function haskell tree binary-tree
除了递归调用左右子树上的 size 函数之外,还有什么方法可以测试二叉树是否平衡。 abs(size left - size right)
【问题讨论】:
标签: function haskell tree binary-tree
所以递归很容易,不是吗?
import Data.Maybe (isJust)
getBalancedSize :: (Monad m, Num b, Ord b) => BinaryTree a -> m b
getBalancedSize Empty = return 0
getBalancedSize (Node _ l r) = do
sizeL <- getBalancedSize l
sizeR <- getBalancedSize r
if abs (sizeL - sizeR) <= 1
then return $ sizeL + sizeR + 1
else fail "tree is not balanced"
isBalanced :: BinaryTree a -> Bool
isBalanced = isJust . getBalancedSize
现在假设你有
fold :: (a -> b -> b -> b) -> b -> Tree a -> b
fold _ b Empty = b
fold f b (Node a l r) = f a (fold f b l) (fold f b r)
有一种明显的方法可以将getBalancedSize 重构为对fold 的一次调用。
getBalancedSize = fold f (return 0) where
f _ l r = do
sizeL <- getBalancedSize l
sizeR <- getBalancedSize r
if abs (sizeL - sizeR) <= 1
then return $ sizeL + sizeR + 1
else fail "tree is not balanced"
但你确实需要一些递归函数来遍历递归树结构。
【讨论】:
这取决于您的二叉树在 Haskell 中的表示方式。如果是递归数据结构,递归是你唯一的武器……
【讨论】:
您可以使用有保证的类型Red-Black Tree。不需要检查它是否平衡,因为类型可以保证它。
isBalanced = const True
【讨论】:
您可以定义一个新的二叉树来存储它的深度。深度在插入和移除时更新,您可以通过查看存储的深度值来判断它是否平衡。
根据更新树的频率进行递归计算是一种更好的解决方案。反正比较干净。
【讨论】:
有效确定一棵树是否平衡而不注意其大小的要点是,一旦您知道正确的分支比正确的分支更深一层以上左分支,它到底有多深并不重要。 2级更深? 3? 100?我们不在乎,只发现结果就扔掉可能被认为是低效的。
isBalanced :: BinaryTree a -> Bool
isBalanced = and . treeToBalanceSize
treeToBalanceSize :: BinaryTree a -> BalanceSize
treeToBalanceSize Empty = []
treeToBalanceSize (Node l r) = True : mergeBalanceSizes (treeToBalanceSize l) (treeToBalanceSize r)
mergeBalanceSizes :: BalanceSize -> BalanceSize -> BalanceSize
mergeBalanceSizes [] [] = []
mergeBalanceSizes [x] [] = [x]
mergeBalanceSizes [] [y] = [y]
mergeBalanceSizes (x : xs) (y : ys) = (x && y) : mergeBalanceSizes xs ys
mergeBalanceSizes _ _ = [False]
type BalanceSize = [Bool]
让自己满意
tree 是平衡的并且大小为size,则treeToBalanceSize tree = replicate size True。tree 不平衡,则treeToBalanceSize tree 将以False 结尾。mergeBalanceSizes [True] list 不会导致评估list 超出其第三个元素。【讨论】: