Created
June 2, 2017 18:03
-
-
Save zlotnleo/bbdb1c419973bbd5897dceae2e536727 to your computer and use it in GitHub Desktop.
2-3-4 Tree
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
datatype 'a tree = | |
Lf | |
| Db of 'a tree * 'a * 'a tree | |
| Tr of 'a tree * 'a * 'a tree * 'a * 'a tree | |
| Qd of 'a tree * 'a * 'a tree * 'a * 'a tree * 'a * 'a tree | |
fun get Lf _ = raise Subscript | |
| get (Db(t1, (k1, v1), t2)) k = | |
if k < k1 then get t1 k | |
else if k = k1 then v1 | |
else get t2 k | |
| get (Tr(t1, (k1, v1), t2, (k2, v2), t3)) k = | |
if k < k1 then get t1 k | |
else if k = k1 then v1 | |
else if k < k2 then get t2 k | |
else if k = k2 then v2 | |
else get t3 k | |
| get(Qd(t1, (k1, v1), t2, (k2, v2), t3, (k3, v3), t4)) k = | |
if k < k2 then | |
if k < k1 then get t1 k | |
else if k = k1 then v1 | |
else get t2 k | |
else if k = k2 then v2 | |
else | |
if k < k3 then get t3 k | |
else if k = k3 then v3 | |
else get t4 k | |
fun min Lf = raise Subscript | |
| min (Db(Lf, m, _)) = m | |
| min (Db(t, _, _)) = min t | |
| min (Tr(Lf, m, _, _, _)) = m | |
| min (Tr(t, _, _, _, _)) = min t | |
| min (Qd(Lf, m, _, _, _, _, _)) = m | |
| min (Qd(t, _, _, _, _, _, _)) = min t | |
fun max Lf = raise Subscript | |
| max (Db(_, m, Lf)) = m | |
| max (Db(_, _, t)) = max t | |
| max (Tr(_, _, _, m, Lf)) = m | |
| max (Tr(_, _, _, _, t)) = max t | |
| max (Qd(_, _, _, _, _, m, Lf)) = m | |
| max (Qd(_, _, _, _, _, _, t)) = max t | |
fun toList Lf = [] | |
| toList (Db(t1, m1, t2)) = toList t1 @ m1 :: toList t2 | |
| toList (Tr(t1, m1, t2, m2, t3)) = toList t1 @ m1 :: toList t2 @ m2 :: toList t3 | |
| toList (Qd(t1, m1, t2, m2, t3, m3, t4)) = toList t1 @ m1 :: toList t2 @ m2 :: toList t3 @ m3 :: toList t4 | |
fun findNodeWithKey Lf _ = raise Subscript | |
| findNodeWithKey (n as Db(t1, (k1, _), t2)) k = | |
if k < k1 then findNodeWithKey t1 k | |
else if k = k1 then n | |
else findNodeWithKey t2 k | |
| findNodeWithKey (n as Tr(t1, (k1, _), t2, (k2, _), t3)) k = | |
if k < k1 then findNodeWithKey t1 k | |
else if k = k1 then n | |
else if k < k2 then findNodeWithKey t2 k | |
else if k = k2 then n | |
else findNodeWithKey t3 k | |
| findNodeWithKey (n as Qd(t1, (k1, _), t2, (k2, _), t3, (k3, _), t4)) k = | |
if k < k1 then findNodeWithKey t1 k | |
else if k = k1 then n | |
else if k < k2 then findNodeWithKey t2 k | |
else if k = k2 then n | |
else if k < k3 then findNodeWithKey t3 k | |
else if k = k3 then n | |
else findNodeWithKey t4 k | |
fun successor tree key = | |
let | |
fun findRight Lf = raise Subscript | |
| findRight (Db(_, (k1, _), t2)) = | |
if key = k1 then t2 | |
else raise Subscript | |
| findRight (Tr(_, (k1, _), t2, (k2, v2), t3)) = | |
if key = k1 then Db(t2, (k2, v2), t3) | |
else if key = k2 then t3 | |
else raise Subscript | |
| findRight (Qd(_, (k1, _), t2, (k2, v2), t3, (k3, v3), t4)) = | |
if key = k1 then Tr(t2, (k2, v2), t3, (k3, v3), t4) | |
else if key = k2 then Db(t3, (k3, v3), t4) | |
else if key = k3 then t4 | |
else raise Subscript | |
fun successorAbove Lf succ = succ | |
| successorAbove (Db(t1, (k1, v1), t2)) succ = | |
if key < k1 then successorAbove t1 (k1, v1) | |
else if key = k1 then succ | |
else successorAbove t2 succ | |
| successorAbove (Tr (t1, (k1, v1), t2, (k2, v2), t3)) succ = | |
if key < k1 then successorAbove t1 (k1, v1) | |
else if key = k1 then succ | |
else if key < k2 then successorAbove t2 (k2, v2) | |
else if key = k2 then succ | |
else successorAbove t3 succ | |
| successorAbove (Qd (t1, (k1, v1), t2, (k2, v2), t3, (k3, v3), t4)) succ = | |
if key < k2 then | |
if key < k1 then successorAbove t1 (k1, v1) | |
else if key = k1 then (k2, v2) | |
else successorAbove t2 (k2, v2) | |
else if key = k2 then succ | |
else | |
if key < k3 then successorAbove t3 (k3, v3) | |
else if key = k3 then succ | |
else successorAbove t4 succ | |
in | |
case findRight (findNodeWithKey tree key) of | |
Lf => | |
let | |
val init = min tree | |
val succ = successorAbove tree init | |
in | |
if succ = init then raise Subscript | |
else succ | |
end | |
| n => min n | |
end | |
fun predecessor tree key = | |
let | |
fun findLeft Lf = raise Subscript | |
| findLeft (Db(t1, (k1, _), _)) = | |
if key = k1 then t1 | |
else raise Subscript | |
| findLeft (Tr(t1, (k1, v1), t2, (k2, _), _)) = | |
if key = k1 then t1 | |
else if key = k2 then Db(t1, (k1, v1), t2) | |
else raise Subscript | |
| findLeft (Qd(t1, (k1, v1), t2, (k2, v2), t3, (k3, _), _)) = | |
if key = k1 then t1 | |
else if key = k2 then Db(t1, (k1, v1), t2) | |
else if key = k3 then Tr(t1, (k1, v1), t2, (k2, v2), t3) | |
else raise Subscript | |
fun predecessorAbove Lf pred = pred | |
| predecessorAbove (Db(t1, (k1, v1), t2)) pred = | |
if key < k1 then predecessorAbove t1 pred | |
else if key = k1 then pred | |
else predecessorAbove t2 (k1, v1) | |
| predecessorAbove (Tr (t1, (k1, v1), t2, (k2, v2), t3)) pred = | |
if key < k1 then predecessorAbove t1 pred | |
else if key = k1 then pred | |
else if key < k2 then predecessorAbove t2 (k1, v1) | |
else if key = k2 then pred | |
else predecessorAbove t3 (k2, v2) | |
| predecessorAbove (Qd (t1, (k1, v1), t2, (k2, v2), t3, (k3, v3), t4)) pred = | |
if key < k2 then | |
if key < k1 then predecessorAbove t1 pred | |
else if key = k1 then (k2, v2) | |
else predecessorAbove t2 (k1, v1) | |
else if key = k2 then pred | |
else | |
if key < k3 then predecessorAbove t3 (k2, v2) | |
else if key = k3 then pred | |
else predecessorAbove t4 (k3, v3) | |
in | |
case findLeft (findNodeWithKey tree key) of | |
Lf => | |
let | |
val init = max tree | |
val pred = predecessorAbove tree init | |
in | |
if pred = init then raise Subscript | |
else pred | |
end | |
| n => max n | |
end | |
fun insert Lf kv = Db(Lf, kv, Lf) | |
| insert (Db(t1, (k1, v1), t2)) (k, v) = | |
if k < k1 then | |
case t1 of | |
Qd(qt1, qm1, qt2, (qk2, qv2), qt3, qm3, qt4) => | |
if k < qk2 then | |
Tr(insert (Db(qt1, qm1, qt2)) (k, v), (qk2, qv2), Db(qt3, qm3, qt4) , (k1, v1), t2) | |
else if k > qk2 then | |
Tr( Db(qt1, qm1, qt2) , (qk2, qv2), insert (Db(qt3, qm3, qt4)) (k, v), (k1, v1), t2) | |
else | |
Db( Qd(qt1, qm1, qt2, (k, v), qt3, qm3, qt4) , (k1, v1), t2) | |
| Lf => | |
Tr( Lf , ( k , v ), Lf , (k1, v1), t2) | |
| _ => | |
Db( insert t1 (k, v) , (k1, v1), t2) | |
else if k = k1 then | |
Db( t1 , (k , v ), t2) | |
else | |
(case t2 of | |
Qd(qt1, qm1, qt2, (qk2, qv2), qt3, qm3, qt4) => | |
if k < qk2 then | |
Tr(t1, (k1, v1), insert (Db(qt1, qm1, qt2)) (k, v), (qk2, qv2), Db(qt3, qm3, qt4) ) | |
else if k > qk2 then | |
Tr(t1, (k1, v1), Db(qt1, qm1, qt2) , (qk2, qv2), insert (Db(qt3, qm3, qt4)) (k, v)) | |
else | |
Db(t1, (k1, v1), Qd(qt1, qm1, qt2, (k, v), qt3, qm3, qt4) ) | |
| Lf => | |
Tr(t1, (k1, v1), Lf , ( k , v ), Lf ) | |
| _ => | |
Db(t1, (k1, v1), insert t2 (k, v) ) | |
) | |
| insert (Tr(t1, (k1, v1), t2, (k2, v2), t3)) (k, v) = | |
if k < k1 then | |
case t1 of | |
Qd(qt1, qm1, qt2, (qk2, qv2), qt3, qm3, qt4) => | |
if k < qk2 then | |
Qd(insert (Db(qt1, qm1, qt2)) (k, v), (qk2, qv2), Db(qt3, qm3, qt4) , (k1, v1), t2, (k2, v2), t3) | |
else if k > qk2 then | |
Qd( Db(qt1, qm1, qt2) , (qk2, qv2), insert (Db(qt3, qm3, qt4)) (k, v), (k1, v1), t2, (k2, v2), t3) | |
else | |
Tr( Qd(qt1, qm1, qt2, (k, v), qt3, qm3, qt4) , (k1, v1), t2, (k2, v2), t3) | |
| Lf => | |
Qd( Lf , ( k , v ), Lf , (k1, v1), t2, (k2, v2), t3) | |
| _ => | |
Tr( insert t1 (k, v) , (k1, v1), t2, (k2, v2), t3) | |
else if k = k1 then | |
Tr( t1 , (k , v ), t2, (k2, v2), t3) | |
else if k < k2 then | |
case t2 of | |
Qd(qt1, qm1, qt2, (qk2, qv2), qt3, qm3, qt4) => | |
if k < qk2 then | |
Qd(t1, (k1, v1), insert (Db(qt1, qm1, qt2)) (k, v), (qk2, qv2), Db(qt3, qm3, qt4) , (k2, v2), t3) | |
else if k > qk2 then | |
Qd(t1, (k1, v1), Db(qt1, qm1, qt2) , (qk2, qv2), insert (Db(qt3, qm3, qt4)) (k, v), (k2, v2), t3) | |
else | |
Tr(t1, (k1, v1), Qd(qt1, qm1, qt2, (k , v), qt3, qm3, qt4) , (k2, v2), t3) | |
| Lf => | |
Qd(t1, (k1, v1), Lf , ( k , v ), Lf , (k2, v2), t3) | |
| _ => | |
Tr(t1, (k1, v1), insert t2 (k, v) , (k2, v2), t3) | |
else if k = k2 then | |
Tr(t1, (k1, v1), t2 , (k , v ), t3) | |
else | |
(case t3 of | |
Qd(qt1, qm1, qt2, (qk2, qv2), qt3, qm3, qt4) => | |
if k < qk2 then | |
Qd(t1, (k1, v1), t2, (k2, v2), insert (Db(qt1, qm1, qt2)) (k, v), (qk2, qv2), Db(qt3, qm3, qt4) ) | |
else if k > qk2 then | |
Qd(t1, (k1, v1), t2, (k2, v2), Db(qt1, qm1, qt2) , (qk2, qv2), insert (Db(qt3, qm3, qt4)) (k, v)) | |
else | |
Tr(t1, (k1, v1), t2, (k2, v2), Qd(qt1, qm1, qt2, (k, v), qt3, qm3, qt4) ) | |
| Lf => | |
Qd(t1, (k1, v1), t2, (k2, v2), Lf , ( k , v ), Lf ) | |
| _ => | |
Tr(t1, (k1, v1), t2, (k2, v2), insert t3 (k, v) ) | |
) | |
| insert (Qd(t1, m1, t2, (k2, v2), t3, m3, t4)) (k, v) = | |
insert (Db(Db(t1, m1, t2), (k2, v2), Db(t3, m3, t4))) (k, v) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment