Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Non-balanced binary tree

I enjoy reading engaging book "Programming in Haskell" (Second Edition) by Graham Hutton. In Chapter "8 Declaring Types and classes", section "8.4 Recursive types", page 97 bottom I find definition of binary tree:

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

This is nice binary tree but I cannot make it with 0, 2, 4, 5, 6, 8, ... elements. I write following file bst.hs:

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

I start Haskell Interpreter in folder and load file.

$ 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.

Ok, one module loaded. But now I try show "leaf" or "tree" (as Leaf or Node) it is good.

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

But I fail miserably to make tree with only {1, 2}. How do I write such tree? I tried:

*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))

Yes I maybe understand how it is wrong but how to make correct?

Only answer to my beginner question is maybe to declare Tree as other suggested Tree on page 99:

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

But how to make original tree with 0, 2, 4, ... elements? Or if not possible, why book not talk about it? There is always must be good reason, so what is reason?

like image 481
Mun Dong Avatar asked Apr 30 '19 04:04

Mun Dong


2 Answers

That definition of a binary tree is a full binary tree, which is

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

It would have been clearer if the type had been named more explicitly:

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

It's a thing, but often you see another definition of a binary tree that allows for empty nodes as well, as you suggest. The empty node is, however, typically named Empty:

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

Both are mathematically valid binary trees, but are obviously not the same. With BinaryTree you can create trees with zero, two, four, etc. values:

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))
like image 134
Mark Seemann Avatar answered Oct 18 '22 05:10

Mark Seemann


Your original definition only allow trees wit odd numbers of elements.

You can fix it with

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

or you can store elements only in leafs

data Tree a = Leaf a | Node (Tree a) (Tree a)
like image 21
talex Avatar answered Oct 18 '22 03:10

talex