Unir & trouver, arbres couvrants
Cours · informatique (MP2I/MPI), chapitre 23 · MP2I et MPI · le début du chapitre, la suite sur Adloun
23.1 Une structure faite pour une seule question
La question est : ces deux éléments sont-ils dans le même paquet ? Et l'opération est : fusionne ces deux paquets. Rien d'autre. On ne sait pas séparer, on ne sait pas énumérer un paquet, on ne sait même pas le nommer autrement que par un représentant arbitraire.
Cette pauvreté est la source de l'efficacité, et le programme la traite comme un cas d'école de la démarche du chapitre chap:abstraction : « on commence par donner des implémentations naïves de la structure unir & trouver qui privilégient soit l'opération unir, soit l'opération trouver, avant de donner une implémentation par des arbres qui permet une mise en œuvre efficace des deux opérations ».
La structure représente une partition d'un ensemble en classes d'équivalence.
| Opération | Rôle | Effet |
|---|---|---|
creer(n) | constructeur | classes, chacune à un élément |
trouver(x) | accesseur | le représentant de la classe de |
unir(x, y) | transformateur | fusionne les classes de et |
Deux éléments sont dans la même classe si et seulement si trouver leur rend le même représentant.
23.2 Deux mises en œuvre naïves
trouverUn tableau où est directement le numéro de classe de .
int trouver(const int c[], int x) { return c[x]; } /* O(1) */
void unir(int c[], int n, int x, int y) { /* O(n) */
int a = c[x], b = c[y];
if (a == b) { return; }
for (int k = 0; k < n; k = k + 1) { if (c[k] == b) { c[k] = a; } }
}
trouver est immédiat, unir doit balayer tout le tableau.
unirChaque élément pointe vers un parent, et l'union se contente d'accrocher une racine sous l'autre.
int trouver(const int p[], int x) { /* O(hauteur) */
while (p[x] != x) { x = p[x]; }
return x;
}
void unir(int p[], int x, int y) { /* O(hauteur) */
p[trouver(p, x)] = trouver(p, y);
}
unir est bon marché — mais rien n'empêche l'arbre de dégénérer en peigne, et trouver devient alors . C'est exactement le défaut de l'arbre binaire de recherche non équilibré du chapitre chap:tas.
23.3 La mise en œuvre efficace
Deux optimisations, chacune tenant en une ligne, et dont la conjonction rend la structure quasi instantanée.
Exercices du chapitre
- Ce que la structure refuse de faire corrigé
- Les deux naïves, chiffrées corrigé
- La faute qui sépare au lieu d'unir corrigé
- La borne est atteinte corrigé
- Le rang ment, et c'est voulu corrigé
- Combien d'arbres couvrants minimaux ? corrigé