{-# LANGUAGE DatatypeContexts #-} -- Binary Search Tree (node valued) examples -- define a (polymorphic) data-type of a (node-valued) tree data (Ord a) => Tree a = Empty | Branch a (Tree a) (Tree a) deriving (Show,Read) -- a function that collects all values from the tree -- Q: in which order will the leaf nodes appear -- Exercise: change this to use an infix order -- Q: what is the property of the list, in infix order, for a binary search tree fringe :: (Ord a) => Tree a -> [a] fringe Empty = [] fringe (Branch x left right) = x : (fringe left ++ fringe right) -- a simple example: compute the depth of the tree depth :: (Ord a) => Tree a -> Int depth Empty = 1 depth (Branch _ left right) = 1 + max (depth left) (depth right) -- check whether this tree is balanced isBalanced :: (Ord a) => Tree a -> Bool isBalanced Empty = True isBalanced (Branch _ left right) = (abs (depth left - depth right)) <= 1 -- version using higher-order functions isSorted :: Tree Int -> Bool isSorted t = and (zipWith (<) xs (tail xs)) where xs = fringe t -- overload the == operator on trees instance (Eq a, Ord a) => Eq (Tree a) where Empty == Empty = True (Branch v1 l1 r1) == (Branch v2 l2 r2) = (v1==v2) && (l1==l2) && (r1==r2) _ == _ = False -- insert a new value into a tree, whose leaf values are sorted -- Q: if the tree is balanced beforehand, will this preserve balanced-ness? insert :: (Ord a) => Tree a -> a -> Tree a insert Empty z = Branch z Empty Empty insert (Branch x left right) z | null (fringe left) = Branch x left (insert right z) | maximum (fringe left) < z = Branch x left (insert right z) | otherwise = Branch x (insert left z) right -- pretty print a tree, using indentation to represent depth pp :: (Show a, Ord a) => Tree a -> IO () pp t = mapM_ putStrLn (pp' 0 t) where pp' n Empty = [] pp' n (Branch x left right) = pp' (n+1) left ++ [(take n (repeat ' ')) ++ (show x)] ++ pp' (n+1) right -- build a balanced tree from a list -- NB: this needs to use insert to generate a search tree mkTree :: (Ord a) => [a] -> Tree a mkTree [] = Empty mkTree xs = mkTree' Empty xs where mkTree' t [] = t mkTree' t (y:ys) = let t' = insert t y in mkTree' t' ys -- sample trees t1 = Branch 5 (Branch 3 (Branch 2 Empty Empty) (Branch 4 Empty Empty)) (Branch 8 Empty Empty) t2 = Branch 1 Empty (Branch 2 Empty (Branch 3 Empty (Branch 4 Empty Empty))) t10 = mkTree [1..10]