【问题标题】:Non-balanced binary tree非平衡二叉树
【发布时间】:2019-04-30 04:26:38
【问题描述】:

我喜欢阅读 Graham Hutton 撰写的引人入胜的书籍“Haskell 编程”(第二版)。在“8 声明类型和类”章节中,“8.4 递归类型”部分,第 97 页底部我找到了二叉树的定义:

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

这是一个不错的二叉树,但我无法使用 0、2、4、5、6、8、... 元素来制作它。我写了以下文件bst.hs

data Tree a = Leaf a | Node (Tree a) a (Tree a)
    deriving (Eq, Ord, Show, Read)

我在文件夹中启动 Haskell Interpreter 并加载文件。

$ ghci
GHCi, version 8.6.4: http://www.haskell.org/ghc/  :? for help
Prelude> :load bst.hs 
[1 of 1] Compiling Main             ( bst.hs, interpreted )
Ok, one module loaded.

好的,加载了一个模块。但是现在我尝试显示“叶子”或“树”(作为叶子或节点)它很好。

*Main> show (Leaf 3)
"Leaf 3"
*Main> show (Node (Leaf 1) 2 (Leaf 3))
"Node (Leaf 1) 2 (Leaf 3)"

但是我很遗憾地没有用 {1, 2} 制作树。我怎么写这样的树?我试过了:

*Main> show (Node (Leaf 1) 2 _)

<interactive>:4:23: error:
    • Found hole: _ :: Tree Integer
    • In the third argument of ‘Node’, namely ‘_’
      In the first argument of ‘show’, namely ‘(Node (Leaf 1) 2 _)’
      In the expression: show (Node (Leaf 1) 2 _)
    • Relevant bindings include
        it :: String (bound at <interactive>:4:1)
*Main> show (Node (Leaf 1) 2)

<interactive>:5:1: error:
    • No instance for (Show (Tree Integer -> Tree Integer))
        arising from a use of ‘show’
        (maybe you haven't applied a function to enough arguments?)
    • In the expression: show (Node (Leaf 1) 2)
      In an equation for ‘it’: it = show (Node (Leaf 1) 2)
*Main> show (Node (Leaf 1) 2 (Node))

<interactive>:6:24: error:
    • Couldn't match expected type ‘Tree Integer’
                  with actual type ‘Tree a0 -> a0 -> Tree a0 -> Tree a0’
    • Probable cause: ‘Node’ is applied to too few arguments
      In the third argument of ‘Node’, namely ‘(Node)’
      In the first argument of ‘show’, namely ‘(Node (Leaf 1) 2 (Node))’
      In the expression: show (Node (Leaf 1) 2 (Node))

是的,我可能明白它是怎么错的,但是如何改正呢?

我的初学者问题的唯一答案可能是将Tree 声明为第 99 页上的其他建议树:

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

但是如何用 0, 2, 4, ... 元素制作原始树呢?或者如果不可能,为什么书不谈论它?总要有好的理由,那么什么是理由呢?

【问题讨论】:

  • 你不能。您的修改似乎是正确的方法
  • @Harald 感谢您的帮助。您能否提供见解为什么教科书不谈论明显的缺陷?这对学习的人来说并不明显:-(仍然必须有充分的理由;什么是理由?

标签: haskell binary-search-tree


【解决方案1】:

二叉树的定义是满二叉树,即

"a tree in which every node has either 0 or 2 children."

如果类型被更明确地命名会更清楚:

data FullBinaryTree a = Leaf a | Node (FullBinaryTree a) a (FullBinaryTree a)

这是一回事,但您经常看到二叉树的另一种定义,它也允许空节点,正如您所建议的那样。然而,空节点通常命名为Empty

data BinaryTree a = Empty | Node (BinaryTree a) a (BinaryTree a) deriving (Eq, Show)

两者都是数学上有效的二叉树,但显然不一样。使用BinaryTree,您可以创建具有零、二、四等值的树:

Prelude> Empty
Empty
Prelude> Node Empty 42 $ Node Empty 1337 Empty
Node Empty 42 (Node Empty 1337 Empty)
Prelude> Node Empty 42 $ Node (Node Empty 1337 Empty) 2112 (Node Empty 91235 Empty)
Node Empty 42 (Node (Node Empty 1337 Empty) 2112 (Node Empty 91235 Empty))

【讨论】:

  • 感谢您的解释和链接,并消除疑虑。令人尴尬的是,我只需要阅读更多内容就尝试了多久。
【解决方案2】:

您的原始定义只允许具有奇数个元素的树。

你可以修复它

data Tree a = Empty | Node (Tree a) a (Tree a)

或者你可以只在叶子中存储元素

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

【讨论】:

  • 感谢您尝试回答。我在问题中写了相同的答案,但答案仍然是答案。我等待其他答案更深入地了解原因。 (Stackoverflow 不让我给 +1 回答,说我没有信誉)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-13
  • 2018-08-30
  • 1970-01-01
  • 2015-01-08
  • 2013-12-18
相关资源
最近更新 更多