{- # OPTIONS_GHC -package haskell98 # -}
{- # LANGUAGE Haskell98 # -}
module Main where -- the code from stackoverflow.com/q/18182507/849891
-- by stackoverflow.com/users/753379/jajdoo
import Data.List -- see stackoverflow.com/q/18278254/849891
import Data.Time.Clock.POSIX -- by stackoverflow.com/users/849891/will-ness
-- import Random -- ___________________________
import System.Random -- works, now -- wn 2019-07-19
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~
data Tree a = Empty |
Branch { key :: a,
left :: Tree a,
right :: Tree a,
--used internally to stop updating balance
}
leaf
:: (Ord a
, Eq a
) => a
-> Tree a
leaf x = Branch x 0 Empty Empty True
-- insert ------------------------------------
treeInsert
:: (Eq a
, Ord a
) => Tree a
-> a
-> Tree a
treeInsert Empty x = leaf x
treeInsert (Branch y b l r _) x
| x < y =
let nl@(Branch _ _ _ _ nlu) = treeInsert l x -- nl = new left
in
if nlu
then if b==1
then roll $ Branch y 2 nl r False
else Branch y (b + 1) nl r (b /= (-1))
else Branch y b nl r False
| x > y =
let nr@(Branch _ _ _ _ nru) = treeInsert r x -- nr = new right
in
if nru
then if b==(-1)
then roll $ Branch y (-2) l nr False
else Branch y (b - 1) l nr (b /= 1)
else Branch y b l nr False
-- rolls -------------------------------------
roll
:: (Eq a
, Ord a
) => Tree a
-> Tree a
-- ll roll
roll (Branch y 2 (Branch ly 1 ll lr _) r _) =
Branch ly 0 ll (Branch y 0 lr r False) False
-- rr roll
roll (Branch y (-2) l (Branch ry (-1) rl rr _) _) =
Branch ry 0 (Branch y 0 l rl False) rr False
-- lr rolls
roll (Branch y 2 (Branch ly (-1) ll (Branch lry lrb lrl lrr _) _) r _) =
case lrb of
0 -> Branch lry 0 (Branch ly 0 ll lrl False)
(Branch y 0 lrr r False) False
1 -> Branch lry 0 (Branch ly 0 ll lrl False)
(Branch y (-1) lrr r False) False
(-1)-> Branch lry 0 (Branch ly 1 ll lrl False)
(Branch y 0 lrr r False) False
-- rl rolls
roll (Branch y (-2) l (Branch ry 1 (Branch rly rlb rll rlr _) rr _) _) =
case rlb of
0 -> Branch rly 0 (Branch y 0 l rll False)
(Branch ry 0 rlr rr False) False
1 -> Branch rly 0 (Branch y 0 l rll False)
(Branch ry (-1) rlr rr False) False
(-1)-> Branch rly 0 (Branch y 1 l rll False)
(Branch ry 0 rlr rr False) False
-- construct a tree --------------------------
construct
:: (Eq a
, Ord a
) => Tree a
-> [a
] -> Tree a
construct = foldl_ treeInsert
-- rands -------------------------------------
rands n low high seed
= take n
$ randomRs
(low
, high
) (mkStdGen seed
)
-- test run
main = do
let ma = 9999999
let t = construct Empty ( rands ma 1 ma seed )
start <- getPOSIXTime
end
<- t `
seq` getPOSIXTime