【问题标题】:Haskell Binary Tree Function (map)Haskell 二叉树函数 (map)
【发布时间】:2011-12-10 14:27:03
【问题描述】:

如何定义一个 Haskell 函数,它将一个函数应用于二叉树中的每个值?所以我知道它类似于map 函数——它的类型是:

mapT :: (a -> b) -> Tree a -> Tree b

但仅此而已......

【问题讨论】:

  • 这是作业吗?如果是这样,请相应地标记。

标签: algorithm haskell binary-tree


【解决方案1】:

您可以声明类Functor 的实例。这是允许映射函数的数据类型的标准类。请注意fmap 的类型与您的mapT 的类型有多相似:

class Functor f where
  fmap :: (a -> b) -> f a -> f b

假设你的树被定义为

data Tree a = Node (Tree a) (Tree a) | Leaf a
  deriving (Show)

那么你可以这样声明Functor的实例:

instance Functor Tree where
  fmap f (Node l r) = Node (fmap f l) (fmap f r)
  fmap f (Leaf x) = Leaf (f x)

你可以这样使用它:

main = do
  let t = Node (Node (Leaf 1) (Leaf 2)) (Leaf 3)
  let f = show . (2^)
  putStrLn $ "Old Tree: " ++ (show t)
  putStrLn $ "New Tree: " ++ (show . fmap f $ t)

输出:

Old Tree: Node (Node (Leaf 1) (Leaf 2)) (Leaf 3)
New Tree: Node (Node (Leaf "2") (Leaf "4")) (Leaf "8")

为方便起见,您也可以定义:

mapT = fmap

当然,你可以在没有类型类的情况下做到这一点,但如果你使用标准函数,它会使代码对其他人更具可读性(每个人都知道fmap 的通常行为)。

【讨论】:

    【解决方案2】:

    我会假装这是家庭作业,而不是给出所有答案。如果我弄错了,我很抱歉。

    您的Tree 类型可能看起来像这样:

    data Tree a = TreeNode a (Tree a) (Tree a) | EmptyNode
    

    这里有两种情况,您需要为每种情况编写一个mapT 实现:

    • 一个内部节点TreeNode,它带有一个a 类型的值,并且有一个左子节点和一个右子节点。这种情况下需要做什么?
    • 终端节点EmptyNode。这种情况下需要做什么?

    【讨论】:

      【解决方案3】:

      地图功能的基本格式适用于两者。我们来看一下list的map函数的定义:

      map f (x:xs) = f x : map f xs
      map _ []     = []
      

      我们可以这样概括:

      1. 你取数据结构中的第一个值
      2. 对它应用函数
      3. 使用数据结构的其余部分递归调用您的 map 函数
      4. 将修改后的值和递归调用都传递给您的类型的构造函数。
      5. 当你到达终点时,停止递归

      您真正需要的只是查看您的构造函数,map 函数应该就位。

      【讨论】:

      • 很久没有写Haskell了……不应该是map f (x:xs) = f x : map f xs吗?
      【解决方案4】:

      如果输入和输出应该是排序二叉树,这是一个有趣的问题。如果你只是天真地遍历树并应用函数,输出树可能不再排序。例如,考虑函数是否是非线性的,比如

      f(x) = x * x - 3 * x + 2
      

      如果输入有 { 1, 2, 3, 4 },那么输出将有 {2, 0, 0, 2 }。输出树应该只包含 0 和 2 吗?

      如果是这样,您可能需要在剥离和处理输入树时迭代地构建输出树。

      【讨论】:

      • 你说得对,这在很多情况下都是一个问题,但我认为在 OP 的情况下这可能会使事情过于复杂。并非所有二叉树都具有其元素都是唯一的甚至按特定顺序排序的属性。例如,二叉树可用于模拟具有廉价随机插入的列表。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-06-04
      • 1970-01-01
      • 2019-04-08
      • 2018-06-29
      • 1970-01-01
      • 2021-11-20
      • 1970-01-01
      相关资源
      最近更新 更多