check if tree is a subtree of another tree - haskell

I am trying to check out if tree is a subtree of another tree. Here is my data for Tree:
data Tree a = Empty | Node a (Tree a)(Tree a) deriving Show
tree1 :: Tree Int
tree1 = Node 1
(Node 2
(Node 4 Empty Empty)
(Node 5 Empty
(Node 8 Empty Empty))
)
(Node 3
(Node 6 Empty
(Node 9 Empty Empty))
(Node 7 Empty Empty)
)
tree2 :: Tree Int
tree2 = Node 2
(Node 4 Empty Empty)
(Node 5 Empty
(Node 8 Empty Empty))
And finally def of unfulfilled function:
isSubTree :: Eq a => Tree a -> Tree a -> Bool
isSubTree _ Empty = False
isSubTree Empty _ = False
isSubTree (Node a l r) (Node b ll rr) |
| otherwise = False
I need a hint how to fulfill first guardian - should i use elem or any other basic function? If I would want to find any specific element in tree I would use code below, so should I somehow modify that code?
treeMember x (Node a l r) |x `elem` [a] = True
|otherwise = treeMember x l || treeMember x r

A tree t1 is a (non-strict) subtree of a tree t2 given the two trees are equal, or t1 is a subtree of one of the (direct) children of t2.
We can let Haskell implement an instance for the Eq typeclass with:
data Tree a = Empty | Node a (Tree a) (Tree a) deriving (Eq, Show)
So now we can implement a check with:
isSubtree :: Eq a => Tree a -> Tree a -> Bool
isSubtree t1 t2 | t1 == t2 = True
isSubtree t1 (Node _ c1 c2) = …
isSubtree _ _ = False
where you still need to fill in the … part. I leave this as an exercise.

Related

Relationships in a Tree (Haskell)

Binary trees with values in the leaves and nodes are defined by:
data Tree a = Leaf a
| Node a (Tree a) (Tree a)
deriving (Eq, Show)
For example,
10
/ \
/ \
8 2
/ \ / \
3 5 2 0
exTree :: Tree Int
exTree = N 10 (N 8 (H 3) (H 5))
(N 2 (H 2) (H 0))
Well, I need a function called RelationshipBinaryTree, which generates a list of tuples, whose first component is an x and its second the father. In this tree,
relationshipBinaryTree :: Tree a -> [(a,a)]
relationshipBinaryTree exTree = [(10,8),(8,3),(8,5),(10,2),(2,2),(2,0)]
Also, I need to define it in the Data.Tree hackage (https://hackage.haskell.org/package/containers-0.5.11.0/docs/Data-Tree.html)
I hope you can help me because I don't understand trees and graphs very well.
I have tried this
relationshipBinaryTree :: Tree a -> [(a,a)]
relationshipBinaryTree (L _) = []
relationshipBinaryTree (N _ (Tree i) (Tree d)) = relationshipBinaryTree (N _) ++ relationshipBinaryTree (Tree i) ++ relationshipBinaryTree (Tree d)
You want to use Data.Tree, but Data.Tree isn't even about binary trees, but about multi way trees (a.k.a. rose trees). However, if you had a function value :: Tree a -> a, then of course you could map it to the children of a rose tree and combine the result with the value.
Now, there exists a function that does that in Data.Tree, it's called rootLabel. And there is another function to geht the children of a node, it's called subForest.
That comes from the definition of Tree in Data.Tree:
Node
rootLabel :: a -- label value
subForest :: Forest a -- zero or more child trees
So we could define for rose trees:
fatherChild :: Tree a -> [(a, a)]
fatherChild t = map mkPair children ++ concatMap fatherChild children
where mkPair child = (rootLabel t, child)
children = subForest t
Example:
fatherChild (Node 3 [Node 8 [], Node 4 []])
> [(3,8),(3,4)]
Your example:
fatherChild (Node 10 [Node 8 [Node 3 [], Node 5 []], Node 2 [Node 2 [], Node 0 []]])
> [(10,8),(10,2),(8,3),(8,5),(2,2),(2,0)]
Now, this doesn't answer your question about binary trees, but I would like to leave that to you as an exercise, because it will be very similar (except if you get stuck). (And please don't use rose trees as binary trees, because there is no type safety to ensure that there are always two children.)
A simple way to do it is by getting the value with an auxiliary function and then do the recursion:
data Tree a = Leaf a
| Node a (Tree a) (Tree a) deriving (Eq, Show)
exTree :: Tree Int
exTree = Node 10 t1 t2
t1 = Node 8 (Leaf 3) (Leaf 5)
t2 = Node 2 (Leaf 2) (Leaf 0)
relationshipBinaryTree :: Tree a -> [(a,a)]
relationshipBinaryTree (Leaf _) = []
relationshipBinaryTree (Node v i d) = [(v, getVal i), (v, getVal d)] ++ relationshipBinaryTree i ++ relationshipBinaryTree d
getVal (Node v _ _) = v
getVal (Leaf v) = v
relationshipBinaryTree exTree
=> [(10,8),(10,2),(8,3),(8,5),(2,2),(2,0)]

writing a recursive function to count the depth of a tree

I have to write a recursive function that, Given a Tree
datatype,will return the depth of the tree. An empty tree should return
0. A single root node Tree should return 1.
expected output:
let treeCons x = (\x -> foldl (flip insertTree) Empty x) x
depth (treeCons []) -> 0
depth (treeCons [5,4,6,3,7,1]) -> 4
depth (treeCons [1,2,5,8,9,4,7]) -> 5
depth (treeCons [5,4,6,3,7,1,2,5,8,9,4,7,8,5,3,4]) -> 6
I wrote the following datatype and insert function:
data Tree a = Node a (Tree a) (Tree a) | Empty deriving (Show, Eq)
insertTree :: (Ord a) => a -> Tree a -> Tree a
insertTree a Empty = Node a Empty Empty
insertTree a (Node b Empty Empty) = if (a <= b) then (Node b (Node a Empty Empty) Empty) else (Node b Empty (Node a Empty Empty))
insertTree a (Node b left right) = if (a <= b) then (Node b (insertTree a left) right ) else (Node b left (insertTree a right))
However, I'm not getting how to write depth function.I'm very new in haskell and I'll appreciate if someone helps me.
An empty tree has depth 0, and a node has depth 1 plus the maximum depth of its child nodes:
depth :: Tree a -> Int
depth Empty = 0
depth (Node _ l r) = 1 + max (depth l) (depth r)
Here you go, is very simple, recursing through a list and a Tree is about the same, only the data types differ. Where you add 1 every time you hit a branch of the tree in question:
tDepth :: Tree a -> Int
tDepth Empty = 0
tDepth (Node _ left right) = 1 + max (tLength left) (tLength right)

What's wrong with my isElement function (binary tree)?

I'm working on a a function that check whether an element is part of a binary tree. I've defined a type for my tree called Tree, functions to get the root element and the left and right subtrees, and a function called isElement for checking whether a value is into my tree. Unfortunately, the function only works with the root element.
The following example illustrates the incorrect results I get from my isElement function:
*Main>let tree = Node 1 Empty (Node 2 Empty (Node 3 Empty Empty))
*Main> isElement tree 2
False
*Main> isElement tree 3
False
*Main> isElement tree 1
True
This is my code:
data Tree a = Node a (Tree a) (Tree a)
|Empty
deriving (Show)
nodeValue :: Tree t -> t
nodeValue (Node x _ _) = x
rightTree :: Tree t -> Tree t
rightTree (Node _ _ x) = x
leftTree :: Tree t -> Tree t
leftTree (Node _ x _) = x
isNode :: Tree t -> Bool
isNode (Node _ _ _) = True
isNode _ = False
isElement :: (Eq t) => Tree t -> t -> Bool
isElement tree t
|isNode tree == False = False
| nodeValue(tree) == t = True
| otherwise = (isElement (leftTree(tree)) t) || (isElement (leftTree(tree)) t)
There is a mistake in the definition of your isElement function: you're calling leftTree twice, instead of calling both leftTree and rightTree. As a result, right subtrees are never explored. Amend the code accordingly,
isElement tree t
|isNode tree == False = False
| nodeValue(tree) == t = True
| otherwise = (isElement (leftTree(tree)) t) || (isElement (rightTree(tree))
and then isElement works as advertised:
λ> let tree = Node 1 Empty (Node 2 Empty (Node 3 Empty Empty))
λ> isElement tree 2
True
λ> isElement tree 3
True
λ> isElement tree 1
True
However, there is still room for improvement. You don't really need all those functions (isNode, nodeValue, etc.) to define isElement. Instead, you can do all that unpacking with pattern matching, by breaking down the definition into two equations: one corresponding to the case where the tree is empty, and another corresponding to the case where the tree is a node:
isElement :: (Eq a) => Tree a -> a -> Bool
isElement Empty _ = False
isElement (Node v l r) x = v == x || isElement l x || isElement r x
Edit: as pointed out by Luis Casillas in his comment, an additional benefit of this alternative definition is that it lends itself better (than the original definition) to exhaustiveness checking by the compiler.

Haskell deleting in a binary search tree

So far I have come up with something like this. What I am trying to do here is get the right most or the leftmost element depending on which is available and swapping them with root and deleting the corresponding rightmost or left most element. I just need some help figuring out why it fails when I ask it to delete root of a tree but it works for all other cases and what does Irrefutable pattern failed mean?
If I do something like delt 3 Node 3 (Node 2 (Node 1 Empty Empty) Empty) (Node 4 Empty Empty)
it gives an error like Node *** Exception: delt.hs:26:40-75: Irrefutable pattern failed for pattern (Main.Node rm (Main.Empty) (Main.Empty))
delt 2 a gives Node 3 (Node 1 Empty Empty) (Node 4 Empty Empty)
data Tree a = Empty | Node a (Tree a) (Tree a) deriving (Show, Read, Eq)
treeIns :: (Ord a) => a -> Tree a -> Tree a
treeIns x Empty= Node x (Empty) (Empty)
treeIns x (Node a l r)
| x == a = Node a l r
| x < a = Node a (treeIns x l) r
| x > a = Node a l (treeIns x r)
leftm :: Tree a -> Tree a
leftm Empty = Empty
leftm (Node a (Empty) (Empty)) = (Node a (Empty) (Empty))
leftm (Node a (l) (Empty)) = leftm l
leftm (Node a (l) (r)) = leftm l
rightm :: Tree a -> Tree a
rightm Empty = Empty
rightm (Node a (Empty) (Empty)) = (Node a (Empty) (Empty))
rightm (Node a (Empty) (r)) = rightm r
rightm (Node a (l) (r)) = rightm r
delt :: (Eq a, Ord a)=>a -> Tree a -> Tree a
delt x Empty = Empty
delt x (Node a (Empty)(Empty))
| x== a = Empty
delt x (Node a l r)
|x == a = (if l /= (Empty) then (let (Node rm (Empty) (Empty)) = rightm l in (Node rm (delt rm l) r)) else (let (Node rm (Empty) (Empty)) = l\
eftm r in (Node rm l (delt rm r)) ))
|x>a = Node a (l) (delt x r)
|x < a = Node a (delt x l ) r
Here is a similar implementation just for reference. (Without the delete part though)
-- a tree can be empty or contain a value with two other Trees
data Tree a = EmptyTree | Node a (Tree a) (Tree a) deriving (Show, Read, Eq)
instance Functor Tree where
fmap f EmptyTree = EmptyTree
fmap f (Node x left right) = Node (f x) (fmap f left) (fmap f right)
-- create a Node with a value and two Empty subtrees (left and right)
singleton :: a -> Tree a
singleton x = Node x EmptyTree EmptyTree
-- insert a new Node into a tree
insertInTree :: (Ord a) => a -> Tree a -> Tree a
-- insert into empty tree is equal to creating a new tree
insertInTree x EmptyTree = singleton x
-- pattern match on value and subtrees
insertInTree x (Node a left right)
-- if element is equal to root element, return same tree
| x == a = Node x left right
-- if element is smaller than root, go to left
-- subtree and check again.
| x < a = Node a (insertInTree x left) right
-- if element is bigger than root, go to right
-- subtree and check again.
| x > a = Node a left (insertInTree x right)
-- binary tree search
search :: (Ord a) => a -> Tree a -> Bool
-- search in EmptyTree is always False
search x EmptyTree = False
-- serach in a Node
search x (Node a left right)
-- if element equals root element, great
| x == a = True
-- if element is smaller than root, continue search on the left side
| x < a = search x left
-- if element is bigger than root, continue search on the right side
| x > a = search x right
-- create a test tree
myTree = foldr insertInTree EmptyTree [15,75,651,2,3,4,85,42,1,5,36,45,78,12,2]

How to delete the root of a tree in Haskell

I have a binary tree.How can we delete the Top of the tree(the root)?I have a function called treeTop which returns the top of the tree,but how to delete it?
thats my tree:
data Tree a = Empty
| Leaf a
| Node a (Tree a) (Tree a) String
deriving (Show)
Assuming this is not a balanced tree, then
deleteRoot :: Tree -> Maybe Tree
deleteRoot (Node _ l r _) = Just $ append l r
deleteRoot _ = Nothing
where append takes on tree, and sticks it on the end of another, implementing this is fairly mechanical
append :: Tree -> Tree -> Tree
append Empty r = r
append (Leaf a) r = <???>
append (Node v l r s) r' = Node v l (append r r') s
Now the problem here is that when you're attempting to append Leaf x to r, it's not clear what to do. With Empty we just throw the value away since it has no useful information, but a Leaf does. You could promote the Leaf to a node with Node a Empty r "" for example, but there isn't a clear value to put in as that String. I'll leave it for you to decide.
This is obviously nonsense when the tree is supposed to be balanced, but if it's not, then we'll turn
foo
/ \
bar baz
/ \ / \
0 0 0 0
Into
bar
/ \
0 baz
/ \
0 0
Where 0 means Empty. Note that the original tree is unmodified, so if we fired up GHCi
Main*> let test = Node () (Node () Empty Empty "bar") (Node () Empty Empty "baz") "foo"
Main*> deleteRoot test
Node Empty (Node Empty Empty "baz") "bar"
Main*> test
Node (Node () Empty Empty "bar") (Node () Empty Empty "baz") "foo"
So it doesn't modify the old text, but this is how things work in functional languages, rather than destroying old data, we keep it and create new immutable values.
My final code ends up as
data Tree a = Empty
| Leaf a
| Node a (Tree a) (Tree a) String
deriving (Show)
deleteRoot :: Tree a -> Maybe (Tree a)
deleteRoot (Node _ l r _) = Just $ append l r
deleteRoot _ = Nothing
append :: Tree a -> Tree a -> Tree a
append Empty r = r
append (Leaf a) r = Node a Empty r ""
append (Node v l r s) r' = Node v l (append r r') s

Resources