在Haskell中检索平衡二叉树的元素

时间:2013-03-27 19:24:28

标签: haskell tree indexing

假设我有以下形式的自定义树数据类型:

data BalTree a = Leaf | Node Integer (BalTree a) a (BalTree a) deriving (Eq, Show, Read)

并创建一个大小为10的新树,我会得到这个:

Node 10 (Node 5 (Node 2 (Node 1 Leaf 'Z' Leaf) 'Z' Leaf)
                 'Z'
                (Node 2 (Node 1 Leaf 'Z' Leaf) 'Z' Leaf))
'Z'
        (Node 4 (Node 2 (Node 1 Leaf 'Z' Leaf) 'Z' Leaf)
                 'Z'
                 (Node 1 Leaf 'Z' Leaf))

如果给定索引,如何在有序横向中检索元素?

我的尝试:

ind Leaf pos            = Nothing
ind tree@(Node n lt x rt) pos
    | pos < 0           = Nothing
    | pos > treeSize-1  = Nothing
    | pos < hTreeSize   = ind lt pos
    | pos == hTreeSize  = Just x
    | pos > hTreeSize   = ind rt (pos - hTreeSize)
    where treeSize = size tree
          hTreeSize = treeSize `div` 2

我不确定这是否是有序的横向并且它不会返回正确的结果。

1 个答案:

答案 0 :(得分:2)

我们希望在顺序遍历中获取存储在二叉树中的第n个值。我们知道以每个节点为根的每个树中存储的值的数量(Integer的{​​{1}}参数)。

Node

这个想法是这样的:假设我们在节点data BalTree a = Leaf | Node Integer (BalTree a) a (BalTree a) size :: BalTree a -> Integer size Leaf = 0 size (Node size _ _ _) = size nthInOrder :: BalTree a -> Integer -> Maybe a nthInOrder Leaf _ = Nothing nthInOrder (Node _ left x right) n | leftSize == n - 1 = Just x | n <= leftSize = nthInOrder left n | otherwise = nthInOrder right (n - leftSize - 1) where leftSize = size left 并且想要A值:

n

如果 A / \ B C 保留B个值,则n-1值为n。如果A包含的值大于或等于B,则我们可以忽略树的其余部分并仅搜索n;所以我们只是进入它。否则,我们应该在B中寻找价值,所以我们将其归入其中;在这种情况下,我们还需要更新C以反映n中有一些值,B中有1个值。

在最坏的情况下,此算法会向下移动到A,因此,复杂度为Leaf。如果树是平衡的,则复杂度为O(depth of tree)