lecture 6 data structures
play

Lecture 6. Data structures Functional Programming 2018/19 Alejandro - PowerPoint PPT Presentation

Lecture 6. Data structures Functional Programming 2018/19 Alejandro Serrano [ Faculty of Science Information and Computing Sciences] 0 Goals Practice our Haskell skills Operations on binary trees Common operations Search trees


  1. Lecture 6. Data structures Functional Programming 2018/19 Alejandro Serrano [ Faculty of Science Information and Computing Sciences] 0

  2. Goals Practice our Haskell skills ▶ Operations on binary trees ▶ Common operations ▶ Search trees ▶ Key-value maps ▶ Via lists and via functions [ Faculty of Science Information and Computing Sciences] 1

  3. Binary search trees [ Faculty of Science Information and Computing Sciences] 2

  4. | Node (Tree a) a (Tree a) data Tree a = Leaf Defjnition of Tree Binary trees with data in the nodes [ Faculty of Science Information and Computing Sciences] 3

  5. Leaf Leaf Leaf Node 7 Leaf Node 6 Leaf Leaf Node 3 Leaf Node 1 Node 2 Node 4 (Node Leaf 6 (Node Leaf 7 Leaf)) 4 (Node Leaf 3 Leaf)) 2 Node (Node (Node Leaf 1 Leaf) Example of tree [ Faculty of Science Information and Computing Sciences] 4

  6. | Node (Tree a) (Tree a) data Tree a = Leaf a data Tree a b = Leaf a | Node (Tree a b) b (Tree a b) data Tree a = Leaf | Node a (Tree a) (Tree a) (Tree a) Other kinds of trees ▶ Binary trees with data in the leaves ▶ Binary trees with data in nodes and leaves ▶ Potentially of difgerent type ▶ Ternary trees with data in the nodes [ Faculty of Science Information and Computing Sciences] 5

  7. | Node a [Tree a] data RoseTree a = Leaf a data RoseTree a = Node a [Tree a] data RoseTree a = a :> [Tree a] Rose trees Trees with an unbound number of branches at each node We do not really need Leaf , we can make the list empty In the practicals, we use an infjx constructor [ Faculty of Science Information and Computing Sciences] 6

  8. size :: Tree a -> Int = _ size (Node l x r) = _ size Leaf = 0 size (Node l x r) = 1 + size l + size r Cooking size size t returns the number of (inner) nodes in t 1. Defjne the type 2. Enumerate the cases size Leaf 3. Defjne the cases ▶ Each recursive position leads to a recursive call [ Faculty of Science Information and Computing Sciences] 7

  9. 3. Defjne the cases mirror Leaf mirror (Node l x r) = Node (mirror r) x (mirror l) = _ = Leaf mirror (Node l x r) = _ mirror :: Tree a -> Tree a (Node Leaf 2 (Node Leaf 3 Leaf)) > mirror (Node (Node Leaf 3 Leaf) 2 Leaf) Cooking mirror mirror t returns the “mirror” image of t 1. Defjne the type 2. Enumerate the cases mirror Leaf [ Faculty of Science Information and Computing Sciences] 8

  10. mirror (Node l x r) = Node (mirror r) x (mirror l) = _ = Leaf mirror Leaf mirror (Node l x r) = _ mirror :: Tree a -> Tree a (Node Leaf 2 (Node Leaf 3 Leaf)) > mirror (Node (Node Leaf 3 Leaf) 2 Leaf) Cooking mirror mirror t returns the “mirror” image of t 1. Defjne the type 2. Enumerate the cases mirror Leaf 3. Defjne the cases [ Faculty of Science Information and Computing Sciences] 8

  11. [2,3] > enumInfix (Node (Node Leaf 2 Leaf) 3 Leaf) enumInfix :: Tree a -> [a] enumInfix Leaf = _ enumInfix (Node l x r) = _ Cooking enumInfix enumInfix t returns the values of t in infjx order ▶ From left-most to right-most ▶ The data in the node in between that of the subtrees 1. Defjne the type 2. Enumerate the cases [ Faculty of Science Information and Computing Sciences] 9

  12. enumInfix (Node l x r) = enumInfix l = [] ++ [x] ++ enumInfix r Cooking enumInfix 3. Defjne the simple (base) cases enumInfix Leaf 4. Defjne the other (recursive) cases ▶ Repeated calls to (++) are very expensive! ▶ Solution: use an accumulator [ Faculty of Science Information and Computing Sciences] 10

  13. enumInfix t = enumInfix' t [] where enumInfix' t acc = _ where enumInfix' Leaf acc = acc enumInfix' (Node l x r) acc = enumInfix' l (x : enumInfix' r acc) enumInfix with an accumulator 1. Introduce a local defjnition with an extra argument 2. Initialize the function in the main call 3. Follow Hutton’s recipe, but ▶ Do not pattern match on the accumulator ▶ Return the accumulator in the base case ▶ Update the accumulator in the recursive steps enumInfix t = enumInfix' t [] [ Faculty of Science Information and Computing Sciences] 11

  14. elem :: Eq a => a -> [a] -> Bool elem _ [] = False elem e (x:xs) | e == x = True | otherwise = elem e xs Linear search is expensive ▶ We check the elements one by one for equality ▶ If the element is not there, we make n comparisons! ▶ where n is the length of the list ▶ On average, we make n 2 comparisons Technical note : we say that linear search has O ( n ) complexity [ Faculty of Science Information and Computing Sciences] 12

  15. Linear search is expensive Suppose that we guarantee that the input list is sorted Can we make linear search better? [ Faculty of Science Information and Computing Sciences] 13

  16. elem e (x:xs) | e == x -- (!) elem :: Ord a => a -> [a] -> Bool elem _ [] = False | otherwise = elem e xs = True | e < x = False Linear search in ordered lists If we guarantee that the list is sorted, we can stop earlier Still, we look at all the elements before the one we search ▶ To do even better we need binary search [ Faculty of Science Information and Computing Sciences] 14

  17. Node (Node Leaf 3 Leaf) 2 (Node Leaf 4 Leaf) -- Not a search tree, 3 > 2 -- A search tree with the same data Node (Node Leaf 2 Leaf) 3 (Node Leaf 4 Leaf) Search trees Search trees are binary trees with a restriction over nodes ▶ All elements in the left subtree must be smaller than the data in the node ▶ Conversely, all elements in the right subtree must be larger than the data in the node [ Faculty of Science Information and Computing Sciences] 15

  18. elem _ Leaf elem :: Ord a => a -> Tree a -> Bool = False elem e (Node l x r) | e == x = True | e < x = elem e l | e > x = elem e r Binary search The ordering guides us on which subtree to consider If the tree is “nicely built”, we get O (log n ) complexity [ Faculty of Science Information and Computing Sciences] 16

  19. toSearchTree [] toSearchTree :: Ord a => [a] -> Tree a = Leaf toSearchTree (x:xs) = insert x (toSearchTree xs) -- Even better with a fold toSearchTree :: Ord a => [a] -> Tree a Building a search tree We build the tree by repeated insertion ▶ insert x t adds the element x to the search tree t , respecting all the restrictions toSearchTree = foldr insert Leaf [ Faculty of Science Information and Computing Sciences] 17

  20. 2. Enumerate the cases insert e Leaf 3. Defjne the simple (base) cases If the tree is empty, we build one with the value insert e Leaf = Node Leaf e Leaf insert :: Ord a => a -> Tree a -> Tree a = _ insert e (Node l x r) = _ Cooking insert 1. Defjne the type [ Faculty of Science Information and Computing Sciences] 18

  21. = _ insert :: Ord a => a -> Tree a -> Tree a insert e (Node l x r) = _ insert e Leaf = Node Leaf e Leaf Cooking insert 1. Defjne the type 2. Enumerate the cases insert e Leaf 3. Defjne the simple (base) cases ▶ If the tree is empty, we build one with the value [ Faculty of Science Information and Computing Sciences] 18

  22. x (insert e r) = -- It's already there | otherwise = Node l = Node (insert e l) x r x | e < x r Node l | e == x insert e (Node l x r) Cooking insert 4. Defjne the other (recursive) cases ▶ We need to compare the value with the node to decide where to continue ▶ We prevent duplicates by an additional equality check [ Faculty of Science Information and Computing Sciences] 19

  23. sort :: Ord a => [a] -> [a] sort = enumInfix . toSearchTree sort for free! 1. Take a list xs 2. Build a search tree toSearchTree xs ▶ The left-most element is the smallest ▶ The right-most element is the largest 3. Turn it back into a list with enumInfix 4. The resulting list is sorted! [ Faculty of Science Information and Computing Sciences] 20

  24. Leaf Node 5 Leaf > toSearchTree [1,2,3,4,5] Node Leaf 1 (Node Leaf 2 ...)) Node 1 Leaf Node 2 Leaf Node 3 Leaf Node 4 Leaf Unbalanced search trees We win nothing by building this search tree [ Faculty of Science Information and Computing Sciences] 21

  25. Leaf Node 5 Leaf Node 3 Node 2 Leaf Node 1 Leaf Leaf Node 4 Leaf Balanced search trees Self-balancing trees keep their height at a minimum ▶ Close to the optimal minimum of log 2 n ▶ 2-3 trees, red-black trees, AVL trees, … Reference: Purely Functional Data Structures by Okasaki [ Faculty of Science Information and Computing Sciences] 22

  26. = _ delete :: Ord a => a -> Tree a -> Tree a delete e (Node l x r) = _ delete e Leaf = Leaf Delete from a search tree delete e t returns the search tree t with e removed ▶ Respecting all the invariants from being a search tree 1. Defjne the type 2. Enumerate the cases delete e Leaf 3. Defjne the simple (base) cases ▶ There is nothing to remove from an empty tree [ Faculty of Science Information and Computing Sciences] 23

  27. | e == x delete e (Node l x r) = _ -- perform the deletion | e < x = Node (delete e l) x r | otherwise = Node l x (delete e r) Delete from a search tree 4. Defjne the other (recursive) cases ▶ We need to decide whether we have arrived to the node we want to remove [ Faculty of Science Information and Computing Sciences] 24

Recommend


More recommend