【问题标题】:Haskell Tree helpHaskell 树帮助
【发布时间】:2010-08-18 12:45:15
【问题描述】:

谁能帮我解决我的作业问题?我已经完成了大部分工作,但我仍然停留在这 3 个问题上。

问题来了:

考虑以下类型的搜索树平衡树

data STree = Leaf | Node STree Int STree  
data Btree = Tip Int | Branch Btree Btree

其构造函数受以下约束:

  • Node left n right 形式的值必须使左侧的所有整数最多为 n,并且右侧的所有整数都大于 n
  • Branch left right 形式的值在 leftright 中的整数个数之间的差值最多为 1。

a) 定义一个递归函数stree :: [Int] -> STree,它从整数列表中构造一个搜索树。

b) 定义一个递归函数btree :: [Int] -> BTree,它从一个非空整数列表构造一个平衡树。

c) 使用合并,定义一个递归函数collapse :: BTree -> [Int],它折叠平衡树以给出排序的整数列表。

请帮帮我!!!

提前非常感谢!

【问题讨论】:

  • 您的问题有两个部分。首先,关于二叉树的必要算法的设计。其次,它们在 Haskell 中的实现。澄清您在解决问题方面的进展,以及您需要帮助的步骤。
  • 到目前为止你有什么?
  • 致“gbacon”:事实上,这部分有5个问题,但我已经完成了2个并坚持了上面的3个问题。其他2个问题是:“flatten”和“merge” {-flatten question-} flatten :: Tree -> [Int] flatten (Leaf n) = [n] flatten (Node l n r) = flatten l ++ [n] ++ 展平 r 和 {-merge question-} 合并 :: [Int] -> [Int] -> [Int] 合并 []xs = xs 合并 xs[] = xs 合并 (x:xs)(y:ys) = if (x

标签: haskell


【解决方案1】:

不想享受所有乐趣,但这是我的第一部分。

stree :: [Int] -> Stree
stree []     = Leaf
stree (x:xs) = let (left, right) = partition (<= x) xs
               in Stree (stree left) x (stree right)

它只取应该在左右两边的组件并递归地为每个组件构建子树。

假设 sort 的使用是合法的,那么我很确定这适用于 b 部分。

btree :: [Int] -> Btree
btree (x:[]) = Tip x
btree xs     = let len = length xs `div` 2
                   ys = sort xs
               in Branch (btree (take len ys)) (btree (drop len ys))

【讨论】:

  • 您可以在stree 中使用partition 代替filter 的两个实例:let (left, right) = partition (&lt;=) xs
  • 好主意,做了必要的修改。
  • 你也可以用 split 代替 take 和 drop。 (left,right) = splitAt len ys in Branch (btree left) (btree right)
  • 从问题陈述中我很确定您不需要对平衡树进行排序。至少你不需要在每个递归步骤都这样做,因为ys 的子列表仍然会被排序!
  • 非常感谢大家,我想我现在可以对最后一个问题有所了解了。
【解决方案2】:
stree = foldr insert Leaf
  where insert :: Int -> STree -> STree
        insert i (Node l i' r)  | i <= i'   = Node (insert i l) i' r
                                | otherwise = Node l i' (insert i r)
        insert i (Leaf) = Node Leaf i Leaf

这不是一个非常有效的解决方案,也不会产生一个非常平衡的树,但它是如何在 Haskell 中迭代构建数据结构的一个很好的例子。使用foldr 为我们处理迭代,我们一次将一个元素插入到树中,将新树传递给构建下一棵树的函数。我们向下遍历树,直到找到一片叶子,然后用 Node 替换 Leaf 以保存给定的值。

【讨论】:

    【解决方案3】:

    这些是递归数据结构。让我们从搜索树开始:

    data STree = Leaf | Node STree Int STree
    

    并且左侧的所有值都必须小于父级,父级必须小于右侧的所有值。你能写下 stree [] 和 stree [x] 的答案吗?你能走多远?

    我要开始了:

    stree [] = Leaf
    stree [x] = Node Leaf x Leaf
    stree ([x,y]) = if x < y then Node Leaf x (Node Leaf y Leaf) else Node (Node Leaf y Leaf) x Leaf
    

    这种嵌套的 if 和节点构造会很快变得非常糟糕。我们可以分解出哪些常见的子表达式?

    singleton x = Node Leaf x Leaf
    

    这让生活更轻松:

    stree [] = Leaf
    stree [x] = singleton x
    stree ([x,y]) = if x < y then Node Leaf x (singleton y) else Node (singleton y) x Leaf
    

    但它并没有解决嵌套 if 的基本问题。列表的一个常见技巧是一次获取一个元素。这对我们有用吗?

    addToSTree :: Int -> STree -> STree
    addToStree x Leaf = singleton x
    addToStree x (Node left n right) | x < n = ...
                                     | otherwise = ...
    

    你能把上面的点填上吗?一旦你有了它,就可以对列表的内容进行循环了。

    BTree也可以类似解决。

    【讨论】:

      猜你喜欢
      • 2011-05-10
      • 1970-01-01
      • 1970-01-01
      • 2012-01-18
      • 1970-01-01
      • 2012-08-12
      • 2022-01-15
      • 2023-03-26
      • 1970-01-01
      相关资源
      最近更新 更多