----------------------------------------------------------------------------- -- | -- Module : Data.Tree.AVL.Read -- Copyright : (c) Adrian Hey 2004,2005 -- License : BSD3 -- -- Maintainer : http://homepages.nildram.co.uk/~ahey/em.png -- Stability : stable -- Portability : portable ----------------------------------------------------------------------------- module Data.Tree.AVL.Read (-- * Reading from AVL trees -- ** Reading from extreme left or right assertReadL,tryReadL, assertReadR,tryReadR, -- ** Reading from /sorted/ AVL trees genAssertRead,genTryRead,genTryReadMaybe,genDefaultRead, -- ** Simple searches of /sorted/ AVL trees genContains, ) where import Prelude -- so haddock finds the symbols there import Data.COrdering import Data.Tree.AVL.Types(AVL(..)) -- | Read the leftmost element from a /non-empty/ tree. Raises an error if the tree is empty. -- If the tree is sorted this will return the least element. -- -- Complexity: O(log n) assertReadL :: AVL e -> e assertReadL E = error "assertReadL: Empty tree." assertReadL (N l e _) = readLE l e assertReadL (Z l e _) = readLE l e assertReadL (P l _ _) = readLNE l -- BF=+1, so left sub-tree cannot be empty. -- | Similar to 'assertReadL' but returns 'Nothing' if the tree is empty. -- -- Complexity: O(log n) tryReadL :: AVL e -> Maybe e tryReadL E = Nothing tryReadL (N l e _) = Just $! readLE l e tryReadL (Z l e _) = Just $! readLE l e tryReadL (P l _ _) = Just $! readLNE l -- BF=+1, so left sub-tree cannot be empty. -- Local utilities for the above readLNE :: AVL e -> e readLNE E = error "readLNE: Bug." readLNE (N l e _) = readLE l e readLNE (Z l e _) = readLE l e readLNE (P l _ _) = readLNE l -- BF=+1, so left sub-tree cannot be empty. readLE :: AVL e -> e -> e readLE E e = e readLE (N l e _) _ = readLE l e readLE (Z l e _) _ = readLE l e readLE (P l _ _) _ = readLNE l -- BF=+1, so left sub-tree cannot be empty. -- | Read the rightmost element from a /non-empty/ tree. Raises an error if the tree is empty. -- If the tree is sorted this will return the greatest element. -- -- Complexity: O(log n) assertReadR :: AVL e -> e assertReadR E = error "assertReadR: Empty tree." assertReadR (P _ e r) = readRE r e assertReadR (Z _ e r) = readRE r e assertReadR (N _ _ r) = readRNE r -- BF=-1, so right sub-tree cannot be empty. -- | Similar to 'assertReadR' but returns 'Nothing' if the tree is empty. -- -- Complexity: O(log n) tryReadR :: AVL e -> Maybe e tryReadR E = Nothing tryReadR (P _ e r) = Just $! readRE r e tryReadR (Z _ e r) = Just $! readRE r e tryReadR (N _ _ r) = Just $! readRNE r -- BF=-1, so right sub-tree cannot be empty. -- Local utilities for the above readRNE :: AVL e -> e readRNE E = error "readRNE: Bug." readRNE (P _ e r) = readRE r e readRNE (Z _ e r) = readRE r e readRNE (N _ _ r) = readRNE r -- BF=-1, so right sub-tree cannot be empty. readRE :: AVL e -> e -> e readRE E e = e readRE (P _ e r) _ = readRE r e readRE (Z _ e r) _ = readRE r e readRE (N _ _ r) _ = readRNE r -- BF=-1, so right sub-tree cannot be empty. -- | General purpose function to perform a search of a sorted tree, using the supplied selector. -- This function raises a error if the search fails. -- -- Complexity: O(log n) genAssertRead :: AVL e -> (e -> COrdering a) -> a genAssertRead t c = genRead' t where genRead' E = error "genAssertRead failed." genRead' (N l e r) = genRead'' l e r genRead' (Z l e r) = genRead'' l e r genRead' (P l e r) = genRead'' l e r genRead'' l e r = case c e of Lt -> genRead' l Eq a -> a Gt -> genRead' r -- | General purpose function to perform a search of a sorted tree, using the supplied selector. -- This function is similar to 'genAssertRead', but returns 'Nothing' if the search failed. -- -- Complexity: O(log n) genTryRead :: AVL e -> (e -> COrdering a) -> Maybe a genTryRead t c = genTryRead' t where genTryRead' E = Nothing genTryRead' (N l e r) = genTryRead'' l e r genTryRead' (Z l e r) = genTryRead'' l e r genTryRead' (P l e r) = genTryRead'' l e r genTryRead'' l e r = case c e of Lt -> genTryRead' l Eq a -> Just a Gt -> genTryRead' r -- | This version returns the result of the selector (without adding a 'Just' wrapper) if the search -- succeeds, or 'Nothing' if it fails. -- -- Complexity: O(log n) genTryReadMaybe :: AVL e -> (e -> COrdering (Maybe a)) -> Maybe a genTryReadMaybe t c = genTryRead' t where genTryRead' E = Nothing genTryRead' (N l e r) = genTryRead'' l e r genTryRead' (Z l e r) = genTryRead'' l e r genTryRead' (P l e r) = genTryRead'' l e r genTryRead'' l e r = case c e of Lt -> genTryRead' l Eq mba -> mba Gt -> genTryRead' r -- | General purpose function to perform a search of a sorted tree, using the supplied selector. -- This function is similar to 'genAssertRead', but returns a the default value (first argument) if -- the search fails. -- -- Complexity: O(log n) genDefaultRead :: a -> AVL e -> (e -> COrdering a) -> a genDefaultRead d t c = genRead' t where genRead' E = d genRead' (N l e r) = genRead'' l e r genRead' (Z l e r) = genRead'' l e r genRead' (P l e r) = genRead'' l e r genRead'' l e r = case c e of Lt -> genRead' l Eq a -> a Gt -> genRead' r -- | General purpose function to perform a search of a sorted tree, using the supplied selector. -- Returns True if matching element is found. -- -- Complexity: O(log n) genContains :: AVL e -> (e -> Ordering) -> Bool genContains t c = genContains' t where genContains' E = False genContains' (N l e r) = genContains'' l e r genContains' (Z l e r) = genContains'' l e r genContains' (P l e r) = genContains'' l e r genContains'' l e r = case c e of LT -> genContains' l EQ -> True GT -> genContains' r