-- file: splay.hs
import Prelude hiding (null)
data (Ord n) => Splay n = Leaf
| Bin n (Splay n) (Splay n)
deriving (Show)
null Leaf = True
null (Bin {}) = False
singleton k = Bin k Leaf Leaf
toList Leaf = []
toList (Bin k l r) = toList l ++ [k] ++ toList r
fromSorted [] = Leaf
fromSorted (x : xs) = Bin x Leaf (fromSorted xs)
splay Leaf _ = Leaf
splay tr k =
let
(kk, ll, rr) = lookup tr [] []
in
Bin kk (connl ll) (connr rr)
where
connl [] = Leaf
connl lts = foldl1 ( acc (Bin k l _) -> (Bin k l acc)) lts
connr [] = Leaf
connr rts = foldl1 ( acc (Bin k _ r) -> (Bin k acc r)) rts
lookup tr@(Bin tk lt rt) lts rts =
if k == tk then
(tk, lt : lts, rt : rts)
else if k < tk then
if null lt then
(tk, lt : lts, rt : rts)
else
let
(Bin ltk _ _) = lt
tr1@(Bin tk1 lt1 rt1) =
if k < ltk then
zig tr
else
tr
in
if null lt1 then
(tk1, lt1 : lts, rt1 : rts)
else
lookup lt1 lts (tr1 : rts)
else
if null rt then
(tk, lt : lts, rt : rts)
else
let
(Bin rtk _ _) = rt
tr1@(Bin tk1 lt1 rt1) =
if k > rtk then
zag tr
else
tr
in
if null rt1 then
(tk1, lt1 : lts, rt1 : rts)
else
lookup rt1 (tr1 : lts) rts
where
zig (Bin x (Bin y at bt) ct) = Bin y at (Bin x bt ct)
zag (Bin y at (Bin x bt ct)) = Bin x (Bin y at bt) ct
insert Leaf x = singleton x
insert tr x =
let (Bin k l r) = splay tr x in
if x < k then
Bin x l (Bin k Leaf r)
else
Bin x (Bin k l Leaf) r
delete Leaf x = Leaf
delete tr x =
let tr1@(Bin k l r) = splay tr x in
if x /= k then
tr1
else
if null l then
r
else
let (Bin kk _ rr) = splay r (x - 1) in
Bin kk l rr
-