【问题标题】:How can I create an indexed binary tree from a sorted list in Haskell?如何从 Haskell 中的排序列表创建索引二叉树?
【发布时间】:2021-05-21 09:36:26
【问题描述】:

我正在尝试从排序列表中创建一棵树,以便以后可以搜索它。

问题是

如果找到,我必须返回数字的索引,否则我返回-1,所以我创建了这个函数。

data Tree e i = Leaf e i | Node (Tree e i) e i (Tree e i)
    

occurs :: Int -> Tree Int Int -> Int 
occurs x (Leaf y i)     | x == y    = i 
                        | otherwise = -1
occurs x (Node l y i r) | x == y    = i 
                        | x < y     = occurs x l 
                        | otherwise = occurs x r 

我的输入格式为(作为字符串)

3       # The length of as
1 5 7   # as
2       # The length of bs
5 6     # bs

我收到 2 个列表 asbs as 将成为树,bs 是我要检查它们是否存在于树中的数字(以及存在于何处)

预期的输出是:

1
-1

在索引 1 上找到 5 而没有找到 6 所以我返回 -1

所以我正在解析输入:

parse :: [Int] -> ([Int], [Int])
parse (n: xs) = (take n xs, tail $ drop n xs) 

solve :: [Int] -> [Int]
solve xs = func as bs
    where (as, bs) = parse xs

main ::IO ()
main = interact $ unlines . map show . solve . map read . words

然后我需要调用一个函数func,它将从as 列表中创建我的树,然后使用occurs 函数在树中搜索bs 中的每个元素

所以我的问题是

  • 如何制作树以使其包含列表中的索引?
  • 我的类型是针对这个问题以正确的方式创建的吗?

我的 Haskell 级别 = 达到了类型和类章节,在 GH 的 Cambridge Haskell 书中,并在 youtube 上关注 HaskellRank 系列。

【问题讨论】:

  • 与问题没有直接关系,但返回 Int 并用 -1 人为地表示不存在的索引不是“Haskell 方式”,尽管它在其他语言中很常见。它需要样板来确保索引是非负的,如果您希望找到元素,这很容易忘记。最好返回Maybe Int,如果找不到元素,则返回Nothing - 这更具描述性,也意味着您不能将结果视为Int 而不处理它不存在的情况'不存在。
  • 看起来您的树必须是 BST 才能使您的 occurs 函数正常工作。您可能需要一些 insert 函数,给定一个 BST 和一个键元素对,将其插入 BST(通过返回一个新的 BST)。这可能会产生平衡的 BST(例如 AVL、红黑……),但重要的部分是它必须产生 BST。然后你可以利用这个insert 函数来构建你的树,逐个处理元素。 (当然,其他方法也是可能的。)

标签: algorithm haskell data-structures binary-tree


【解决方案1】:

您可以使用分而治之的方法构建二叉搜索树,并保留类似版本的“发生”方法:

  1. 以有序列表中心的元素为根。如果有平局(列表长度相等),请选择您喜欢的任何一个。没关系。
  2. 递归解决所选索引左侧所有元素的问题,并将返回的树添加为当前根的左子节点。如果左侧没有元素,则在左侧子节点上添加一个空引用。
  3. 递归解决所选索引右侧的所有元素的问题,并将返回的树添加为当前根的右孩子。如果右侧没有元素,则在右侧子节点上添加一个空引用。

这种分而治之的方法保证了树的 O(log n) 高度,其中 n 是有序列表的长度。树的构造是 O(n) 并且是正确的二叉搜索树,因为随着列表的排序,我们知道左侧的所有元素都小于或等于当前元素,而右侧的所有元素都大于或等于当前的。

类型创建是一个缺陷,因为您构建树依赖于叶节点和不具有左右子节点的节点,这在几乎任何输入中都是不正确的。您可以尝试构建一棵具有 2 个节点的树来了解我的意思。其他不是这样的 Haskell 设计是使用 -1 作为不存在的解决方案,因为 Haskell 具有为这些情况创建的可能的集成类型,但如果您需要这样做,最后是您的选择。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-13
    • 2017-12-05
    • 2013-12-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多