73 lines
2.2 KiB
OCaml
73 lines
2.2 KiB
OCaml
type 'a arbre =
|
|
| Vide
|
|
| Noeud of int * 'a * 'a arbre * 'a arbre;;
|
|
|
|
let taille t = match t with
|
|
| Vide -> 0
|
|
| Noeud(i,_,_,_) -> i;;
|
|
|
|
let rec hauteur t = match t with
|
|
| Vide -> -1
|
|
| Noeud(_,_,fg, fd) -> 1 + max (hauteur fg) (hauteur fd);;
|
|
|
|
let creer_noeud a fg fd = Noeud((1+(taille fg)+(taille fd)), a, fg, fd);;
|
|
|
|
let rec recalculer_taille t = match t with
|
|
|Vide -> Vide
|
|
|Noeud(_,a,fg,fd) -> creer_noeud a (recalculer_taille fg) (recalculer_taille fd);;
|
|
let test =recalculer_taille (creer_noeud 5 (Noeud(1,0,Noeud(2,-2,Vide,Vide),Noeud(1,2,Noeud(0,1,Vide,Vide),Noeud(1,3,Vide,Vide)))) (Noeud(0, 10, Vide, Vide)));;
|
|
|
|
let elements t =
|
|
let rec aux acc f = match f with
|
|
| Vide -> acc
|
|
| Noeud(i, e, fg, fd) -> aux (e::(aux acc fg)) fd in
|
|
List.rev (aux [] t);;
|
|
|
|
elements test;;
|
|
|
|
(* II ABR avec annotations de taille *)
|
|
(*5 : Le parcours infixe est croissant si et seulement si l'arbre est un ABR *)
|
|
let est_abr t=
|
|
let rec croiss l = match l with
|
|
| a::b::t -> (a < b) && croiss (b::t)
|
|
| _ -> true in
|
|
croiss (elements t);;
|
|
est_abr test;;
|
|
|
|
let rec contient e t = match t with
|
|
| Vide -> false
|
|
| Noeud(i,a,fg,fd) -> if e = a then true
|
|
else if e > a then contient e fd
|
|
else contient e fg;;
|
|
contient (-3) test;;
|
|
|
|
let rec insere e t = match t with
|
|
| Vide -> creer_noeud e Vide Vide
|
|
| Noeud(i, a, fg, fd) -> if e > a then creer_noeud a fg (insere e fd)
|
|
else creer_noeud a (insere e fg) fd;;
|
|
|
|
let rec construit l n = match n with
|
|
| 0 -> (Vide,l)
|
|
| _ -> let (t1, h::reste) = construit l (n/2) in let (t2, r) = construit reste ((n-1)/2) in (creer_noeud h t1 t2, r);;
|
|
|
|
construit [1;2;3;4;5;6;7;8] 8;;
|
|
|
|
let alpha = 0.7;;
|
|
|
|
let reconstruit t = match t with
|
|
|Vide -> Vide
|
|
|Noeud(i, _, _ ,_) -> fst (construit (elements t) i);;
|
|
|
|
reconstruit test;;
|
|
|
|
let rebalance t = match t with
|
|
|Vide -> Vide
|
|
|Noeud(i,_,fg,fd) -> let n = float_of_int i in if (float_of_int (taille fg) < alpha*.n ) && (float_of_int (taille fd) < alpha*.n) then t else reconstruit t;;
|
|
rebalance test;;
|
|
|
|
let rec insere_be a t = match t with
|
|
|Vide -> creer_noeud a Vide Vide
|
|
|_ -> let Noeud(i,e,fg,fd) = rebalance t in if a <= e then creer_noeud e (insere_be a fg) fd else creer_noeud e fg (insere_be a fd);;
|
|
insere_be 3 test;;
|
|
|