Haskell's Marathon - Days Twenty Nine to Thirty One
Hey folks!
Last post we improved our build
function and saw some options using the insert
function which we created to add nodes in our BST
.
Now let’s see some functions to find an element in the tree or confirm if the tree contains or not an element.
BST Recap
First let’s do a quick recap how we arrived til here.
We started creating a type to our BST
.
data (Ord a, Eq a) => Tree a = Empty | Node a (Tree a) (Tree a)
deriving Show
In the second post we saw how to build a BST
from a list.
build' :: (Ord a, Eq a) => [a] -> Tree a -> Tree a
build' [] tree = tree
build' (x:xs) Empty = build' xs (Node x Empty Empty)
build' (x:xs) (Node a left right)
| a >= x = build' xs (Node a (build' [x] left) right)
| otherwise = build' xs (Node a left (build' [x] right))
build :: (Ord a, Eq a) => [a] -> Tree a
build xs = build' xs Empty
In the last post we created the insert
function:
singleNode :: (Ord a) => a -> Tree a
singleNode x = Node x Empty Empty
insert :: (Ord a) => Tree a -> a -> Tree a
insert Empty x = singleNode x
insert (Node a left right) x
| a >= x = Node a (insert left x) right
| otherwise = Node a left (insert right x)
Using our insert*
function we saw some options of improvement to *build
function:
build' :: (Ord a, Eq a) => [a] -> Tree a -> Tree a
build' [] tree = tree
build' (x:xs) tree = build' xs $ insert tree x
build :: (Ord a, Eq a) => [a] -> Tree a
build xs = build' xs Empty
build2 :: (Ord a) => [a] -> Tree a
build2 [] = Empty
build2 xs = build2' xs Empty
where
build2' (y:ys) Empty = build2' ys $ insert Empty y
build2' (y:ys) tree = build2' ys $ insert tree y
build3 :: (Ord a) => [a] -> Tree a -> Tree a
build3 [] tree = tree
build3 (x:xs) tree = build3 xs $ insert tree x
Find a Node in the Tree
Now let’s looking for a node inside a BST
and let’s return it as a tree.
find :: (Ord a) => Tree a -> a -> Tree a
find Empty _ = Empty
find (Node a left right) x
| a == x = Node a left right
| a >= x = find left x
| otherwise = find right x
This return a node with its left and right sides according the value received.
Let’s say that we have this tree:
If we call the find
function with value 6 we will receive this BST
as result:
Find a Node in the Tree which is Not Root
Cool, but our BST
has two six and if after we call the find
function over the original tree, received a new tree with a 6 as root and tried to get the second 6. It won’t get the second 6.
So we have a new function to get the second 6:
findSub :: (Ord a) => Tree a -> a -> Tree a
findSub Empty _ = Empty
findSub (Node a left right) x
| a >= x = find left x
| otherwise = find right x
We could do that without a function, but it makes our life easier.
Verify if Tree contains an Element
Our last helper function is to verify if our BST
contains or not a value:
contains :: (Ord a) => a -> Tree a -> Bool
contains _ Empty = False
contains x (Node a left right)
| a > x = contains x left
| a < x = contains x right
| otherwise = True
Thinking in the previous BST
if we call contains
function with value 7 it will return True
and if we call with 5 will return False
.