Fixed AVL balance

This commit is contained in:
Dmitry Boulytchev 2020-07-23 12:52:42 +03:00
parent 9d0b8e811a
commit c73f43e817
2 changed files with 51 additions and 31 deletions

View file

@ -1 +1 @@
let version = "Version 1.00, 423e4e772, Wed Apr 15 21:53:42 2020 +0300" let version = "Version 1.00, 9d0b8e811, Mon May 4 02:45:34 2020 +0300"

View file

@ -25,6 +25,28 @@ fun printColl (m) {
inner ("", m) inner ("", m)
} }
public fun validateColl (t) {
fun inner (t, verify) {
case t of
{} -> 0
| MNode (k, _, bf, l, r) ->
if verify (k)
then
local lh = validateColl (l, fun (x) {x < k}),
rh = validateColl (r, fun (x) {x > k});
if bf == lh - rh
then 1 + if lh > rh then lh else rh fi
else failure ("Collection::validateColl: balance violation on key %s\nTree: %s\n", k.string, t.string) -- 1 + if lh > rh then lh else rh fi
fi
else failure ("Collection::validateColl: order violation on key %s\nTree: %s\n", k.string, t.string)
fi
esac
}
inner (t, fun (x) {true})
}
fun makeCompare (sort) { fun makeCompare (sort) {
case sort of case sort of
Hash -> fun (x, y) { Hash -> fun (x, y) {
@ -56,12 +78,32 @@ fun insertColl (m, pk, v, sort) {
fun rot (left, node) { fun rot (left, node) {
if left if left
then case node of then case node of
MNode (k, v, b, l, MNode (rk, rv, rb, ll, rr)) -> MNode (k, v, x, l, MNode (rk, rv, y, ll, rr)) ->
MNode (rk, rv, 0, MNode (k, v, 0, l, ll), rr) local x0 = if y > 0 then x + 1 else x - y + 1 fi,
y0 = if x0 > 0
then
if y > 0
then x + y + 2
else x + 2
fi
else y + 1
fi;
MNode (rk, rv, y0, MNode (k, v, x0, l, ll), rr)
esac esac
else case node of else case node of
MNode (k, v, b, MNode (lk, lv, lb, ll, rr), r) -> MNode (k, v, x, MNode (lk, lv, y, ll, rr), r) ->
MNode (lk, lv, 0, ll, MNode (k, v, 0, rr, r)) local x0 = if y < 0 then x - 1 else x - y - 1 fi,
y0 = if x0 > 0
then y - 1
else
if y < 0
then y + x - 2
else x - 2
fi
fi;
MNode (lk, lv, y0, ll, MNode (k, v, x0, rr, r))
esac esac
fi fi
} }
@ -82,8 +124,8 @@ fun insertColl (m, pk, v, sort) {
then [false, MNode (kk, vv, bf + 1, ll, r)] then [false, MNode (kk, vv, bf + 1, ll, r)]
elif bf == 1 elif bf == 1
then if ll.factor > 0 then if ll.factor > 0
then [false, rot (false, MNode (kk, vv, bf, ll, r))] then [false, rot (false, MNode (kk, vv, 2, ll, r))]
else [false, rot (false, MNode (kk, vv, bf, rot (true, ll), r))] else [false, rot (false, MNode (kk, vv, 2, rot (true, ll), r))]
fi fi
else [true, MNode (kk, vv, bf + 1, ll, r)] else [true, MNode (kk, vv, bf + 1, ll, r)]
fi fi
@ -95,8 +137,8 @@ fun insertColl (m, pk, v, sort) {
then [false, MNode (kk, vv, bf - 1, l, rr)] then [false, MNode (kk, vv, bf - 1, l, rr)]
elif bf == -1 elif bf == -1
then if rr.factor < 0 then if rr.factor < 0
then [false, rot (true, MNode (kk, vv, bf, l, rr))] then [false, rot (true, MNode (kk, vv, -2, l, rr))]
else [false, rot (true, MNode (kk, vv, bf, l, rot (false, rr)))] else [false, rot (true, MNode (kk, vv, -2, l, rot (false, rr)))]
fi fi
else [true, MNode (kk, vv, bf - 1, l, rr)] else [true, MNode (kk, vv, bf - 1, l, rr)]
fi fi
@ -188,28 +230,6 @@ fun contents (m, sort) {
inner (m, {}) inner (m, {})
} }
public fun validateColl (t) {
fun inner (t, verify) {
case t of
{} -> 0
| MNode (k, _, bf, l, r) ->
if verify (k)
then
local lh = validateColl (l, fun (x) {x < k}),
rh = validateColl (r, fun (x) {x > k});
if bf == lh - rh
then 1 + if lh > rh then lh else rh fi
else 1 + if lh > rh then lh else rh fi -- failure ("Collection::validateColl: balance violation on key %s\n", k.string)
fi
else failure ("Collection::validateColl: order violation on key %s\n", k.string)
fi
esac
}
inner (t, fun (x) {true})
}
-- Map structure -- Map structure
public fun emptyMap () { public fun emptyMap () {
{} {}