-
Notifications
You must be signed in to change notification settings - Fork 2
/
unionfind_entiers.ml
79 lines (63 loc) · 1.88 KB
/
unionfind_entiers.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
(** Structure d'ensembles disjoints, structure dite Union-Find
- Uniquement pour des ensembles d'entiers.
- Note: pour des tout petits entiers, on peut faire bien mieux,
en représentant {i} comme 2^i, {i} u {i} = 2^i + 2^j etc.
@author Lilian Besson <lilian.besson[AT]ens-cachan.fr>
*)
(** {6 Implémentation pour des données entières uniquement, sans foncteur } *)
module EnsemblesDisjointsEntiers = struct
(** Type interne pour un pointeur *)
type t = {
valeur: int;
mutable rang: int;
mutable parent: t option
}
(** Crée un singleton contenant x. *)
let singleton x =
{valeur = x; rang = 0; parent = None}
(** Renvoie le représentant de la classe d'équivalence de x.
Utilise l'optimisation dite de compression des chemins.
Complexité : en [O(alpha(n))].
*)
let rec trouver x =
match x.parent with
| None -> x
| Some(y) -> begin
x.parent <- Some(trouver y);
y
end
(** Unie les deux classes d'équivalence de x et y.
Utilise l'optimisation dite de l'union équilibrée.
Complexité : en [O(alpha(n))].
*)
let union x y =
let xr = trouver x and yr = trouver y in
if xr != yr then (
if xr.rang < yr.rang then
xr.parent <- Some(yr)
else (
if xr.rang > yr.rang then
yr.parent <- Some(xr)
else (
yr.parent <- Some(xr);
xr.rang <- xr.rang + 1
)
)
)
end ;;
(** {6 Exemples} *)
module S = EnsemblesDisjointsEntiers;;
let s1 = S.singleton 1
and s2 = S.singleton 2
and s3 = S.singleton 3
and s4 = S.singleton 4
and s5 = S.singleton 5;;
S.union s1 s2;;
S.union s4 s5;;
S.union s2 s3;;
S.union s3 s1;;
s1;;
s2;;
s3;;
s4;;
s5;;