测试二进制树是否在Haskell中平衡

时间:2011-02-21 04:12:11

标签: function haskell tree binary-tree

除了在左右子树上递归调用size函数之外,测试二叉树是否平衡的另一种方法是什么。 abs(大小左 - 右大小)< = 1表示要平衡的树。我必须编写一个有效的函数来满足要求,但就像我说的那样,不会在左右子树上递归调用size函数。

5 个答案:

答案 0 :(得分:2)

因此递归很容易,不是吗?

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"

但是你确实需要一些递归函数来遍历递归树结构。

答案 1 :(得分:1)

这取决于二进制树在Haskell中的表示方式。如果它是一个递归数据结构,递归是你唯一的武器......

答案 2 :(得分:1)

您可以使用保证类型Red-Black Tree。无需检查它是否平衡,因为类型可以保证它。

isBalanced = const True

答案 3 :(得分:0)

您可以定义一个存储其深度的新二叉树。深度在插入和删除时更新,您可以通过查看存储的深度值来判断它是否平衡。

根据您更新树的频率,递归计算是一个更好的解决方案。反正它更干净。

答案 4 :(得分:0)

关于有效确定树是否平衡而不关注其大小的观点是,一旦你知道正确的分支比一个更深层次,那么左分支,它究竟有多深,无关紧要。 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]

满足自己

  1. 如果tree平衡且尺寸为size,则为treeToBalanceSize tree = replicate size True
  2. 如果tree不平衡,则treeToBalanceSize tree将以False结束。
  3. 评估mergeBalanceSizes [True] list不会导致list超出其第三个元素进行评估。