package grenier
A collection of various algorithms in OCaml
Install
Dune Dependency
Authors
Maintainers
Sources
grenier-0.15.tbz
sha256=dec7f84b9e93d5825f10c7dea84d5a74d7365ede45664ae63c26b5e8045c1c44
sha512=b8aa1569c2e24b89674d1b34de34cd1798896bb6a53aa5a1287f68cee880125e6b687f66ad73da9069a01cc3ece1f0684f48328b099d43529bff736b772c8fd8
doc/src/grenier.baltree/bt1.ml.html
Source file bt1.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
type 'a t = | Leaf | Node of int * 'a t * 'a * 'a t let size = function | Node (s, _, _, _) -> s | Leaf -> 0 (** {1 Balance criteria} Functions are not symmetric. The first argument should always be of the same power of two or smaller (guaranteed by construction). *) (** [smaller_ell smin smax] iff - [smin] is less than [smax] - [smin] and [smax] differs by less than two magnitude orders, i.e msbs(smin) >= msbs(smax) - 1 where msbs is the index of the most significant bit set *) let smaller_ell smin smax = (smin < smax) && ((smin land smax) lsl 1 < smax) (** [disbalanced smin smax] check if two sub-trees of size [smin] and [smax], are disbalanced. That is, msbs(smin) < msbs(smax) - 1 *) let disbalanced smin smax = smaller_ell smin (smax lsr 1) (** {1 Smart but not too much constructors} *) (** Construct node and check balance let node_ l x r = let sl = size l and sr = size r in if sl < sr then assert (not (disbalanced sl sr)) else assert (not (disbalanced sr sl)); Node (sl + 1 + sr, l, x, r) *) (** Construct Node *) let node_ l x r = Node (size l + 1 + size r, l, x, r) (** Rotations *) let rot_left l x r k = match r with | Node (_, rl, y, rr) -> k (k l x rl) y rr | _ -> assert false let rot_right l y r k = match l with | Node (_, ll, x, lr) -> k ll x (k lr y r) | _ -> assert false (** Balancing *) let inc_left l x r k = let r = match r with | Node (_, rl, y, rr) when smaller_ell (size rr) (size rl) -> rot_right rl y rr k | _ -> r in rot_left l x r k let inc_right l y r k = let l = match l with | Node (_, ll, x, lr) when smaller_ell (size ll) (size lr) -> rot_left ll x lr k | _ -> l in rot_right l y r k (** Balance trees leaning to the right *) let rec node_left l x r = if disbalanced (size l) (size r) then inc_left l x r node_left else node_ l x r (** Balance trees leaning to the left *) let rec node_right l y r = if disbalanced (size r) (size l) then inc_right l y r node_right else node_ l y r (** Public interface *) let leaf = Leaf let node l x r = match l, r with | Leaf, Leaf -> node_ leaf x leaf | l, r when size l < size r -> node_left l x r | l, r -> node_right l x r let rec join l r = match l, r with | Leaf, t | t, Leaf -> t | Node (sl, ll, x, lr), Node (sr, rl, y, rr) -> if sl <= sr then node (join l rl) y rr else node ll x (join lr r) let rec rank n = function | Leaf -> raise Not_found | Node (_, l, x, r) -> let sl = size l in if n = sl then x else if n < sl then rank n l else rank (n - 1 - sl) r
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>