algorithm - 如何从 Haskell 中的排序列表创建索引二叉树?

标签 algorithm haskell data-structures binary-tree

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

问题是

如果找到数字,我必须返回该数字的索引,否则我返回-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

其中 5 在索引 1 上找到,但未找到 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 创建我的树,然后使用 occurrs 函数进行搜索bs

中每个元素的树

所以我的问题是

  • 如何创建树以使其包含列表中的索引?
  • 我的类型是否以正确的方式创建来解决这个问题?

我的 Haskell 水平 = 达到 GH 的 Cambridge Haskell 书中的类型和类章节,并关注 YouTube 上的 HaskellRank 系列。

最佳答案

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

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

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

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

关于algorithm - 如何从 Haskell 中的排序列表创建索引二叉树?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66259878/

相关文章:

python - 如何在 Python 的嵌套列表中获取具有最多共同元素的两个列表

arrays - 在 Haskell 中修改数组并记住索引

python - __eq __()多次调用,而不是在嵌套数据结构中一次调用

javascript - 如何根据多笔费用分摊金额拆分费用给不同份额的多个用户?

c++ - 有没有一种很好的方法可以将 std::minmax(a, b) 分配给 std::tie(a, b)?

haskell - 这个 Haskell 输入缩进有什么问题?

haskell - 如何使用 runhaskell 增加堆栈大小?

java - Android从sqlite数据库中获取多个项目

algorithm - 电话簿的数据结构

c# - 更好的 Frog 穿越算法