Vous êtes sur la page 1sur 29

Complexité des algorithmes

Méthodologie des spécifications


Structures de données
Algorithmes de recherche

Structures de données et algorithmes

Béatrice Duval & Igor Stéphan

UFR Sciences Angers

2012-2013

Béatrice Duval & Igor Stéphan SDA 1/ 194


Complexité des algorithmes
Méthodologie des spécifications
Structures de données
Algorithmes de recherche

Les arbres généraux (étiquetés)


Un arbre est une structure hiérarchique sur des nœuds à partir d’un
nœud particulier, la racine.
panier

figues bananes noix

5 vertes mures 23

2 1
noeud( panier ,
{ noeud(figues, {feuille(5)}),
noeud( bananes,
{ noeud(vertes, {feuille(2)}),
noeud(mûres, {feuille(1)})}),
noeud(noix, {feuille(23)})})
Béatrice Duval & Igor Stéphan SDA 65/ 194
Complexité des algorithmes
Méthodologie des spécifications
Structures de données
Algorithmes de recherche

Définitions sur les arbres


racine

...

sous-arbres

Un arbre général est soit vide (Λ) soit de la forme


noeud(v , {B1 , . . . , Bn }) avec B1 , . . . , Bn des arbres généraux
et v une valeur.
Un nœud qui contient une valeur est un nœud étiqueté.
Un nœud qui n’a pas de sous-arbres est une feuille ou un
nœud externe.
Béatrice Duval & Igor Stéphan SDA 66/ 194
Complexité des algorithmes
Méthodologie des spécifications
Structures de données
Algorithmes de recherche

Un nœud qui a des sous-arbres est un nœud interne.


Une forêt est un ensemble d’arbres.
La racine d’un sous-arbre d’un nœud est un fils de ce nœud.
Des nœuds fils d’un même nœud sont frères.
Si un nœud n a pour fils un nœud n′ alors n est le père
(unique) de n′ .
Un nœud n est un ascendant (resp. descendant) ou ancêtre
d’un nœud n′ si n est le père (resp. fils) de n′ ou un ascendant
(resp. descendant) du père (resp. fils) de n′ .
Un chemin est une suite de nœuds consécutifs.
Une branche est un chemin de la racine à une feuille.

Béatrice Duval & Igor Stéphan SDA 67/ 194


Complexité des algorithmes
Méthodologie des spécifications
Structures de données
Algorithmes de recherche

Spécification des arbres généraux

Deux constructeurs d’arbres : l’arbre vide, Λ, et le nœud.


Une opération interne : l’obtention d’un sous-arbre
quelconque.
Trois observateurs : le test de vacuité de l’arbre, l’obtention de
l’ensemble des sous-arbres et l’obtention de la valeur de la
racine.
La forêt d’arbres de sorte E est une instance de la sorte
Ensemble pour les arbres de sorte E :
Ensemble(ArGen(E )).
Nous utilisons un alias sur la sorte Foret pour faciliter
l’écriture.

Béatrice Duval & Igor Stéphan SDA 68/ 194


Complexité des algorithmes
Méthodologie des spécifications
Structures de données
Algorithmes de recherche

specification ARGEN0 (E )
etend BASE(E ), ENSEMBLE(ArGen(E ))

sortes ArGen, ForetaliasEnsemble(ArGen(E ))

operations
Λ : ArGen(E )
noeud : E × Foret → ArGen(E )
sous arbres : ArGen(E ) → Foret
un sous arbre : ArGen(E ) → ArGen(E )
racine : ArGen(E ) → E
vide ? : ArGen(E ) → Bool

Béatrice Duval & Igor Stéphan SDA 69/ 194


Complexité des algorithmes
Méthodologie des spécifications
Structures de données
Algorithmes de recherche

suite de ARGEN0

preconditions {a : ArGen(E )}
pre racine(a) : ¬(vide ?(a))
pre sous arbres(a) : ¬(vide ?(a))
pré un sous arbre(a) : ¬(vide ?(a))
et ¬(vide ?(sous arbres(a)))
axiomes {f : Foret; x : E }
argen(0) : sous arbres(noeud(x, f )) = f
argen(1) : un sous arbre(noeud(x, f )) = choisir (f )
argen(2) : racine(noeud(x, f )) = x
argen(3) : vide ?(Λ) = vrai
argen(4) : vide ?(noeud(x, f )) = faux

Béatrice Duval & Igor Stéphan SDA 70/ 194


Complexité des algorithmes
Méthodologie des spécifications
Structures de données
Algorithmes de recherche

Mesures sur les arbres

Deux opérations fondamentales sur les arbres : la taille et la


hauteur.
La taille est le nombre de nœuds d’un arbre.
La hauteur est la longueur du plus grand chemin interne d’un
arbre.

specification ARGEN1 (E )
etend ARGEN0

operations
taille : ArGen(E ) → Nat
hauteur : ArGen(E ) → Ent

Béatrice Duval & Igor Stéphan SDA 71/ 194


Complexité des algorithmes
Méthodologie des spécifications
Structures de données
Algorithmes de recherche

suite de ARGEN1

axiomes {a1 , . . . , an : ArGen(E ); x : E }


argen1 (0) : taille(Λ) = 0
argen1 (1) : taille(noeud(x, {})) = 1
argen1 (2) : taille(noeud(x, {a1 , . . . , an })) =
1 + Σni==1 taille(ai )
argen1 (3) : hauteur (Λ) = −1
argen1 (4) : hauteur (noeud(x, {})) = 0
argen1 (5) : hauteur (noeud(x, {a1 , . . . , an })) =
n
1 + maxi==1 hauteur (ai )

Béatrice Duval & Igor Stéphan SDA 72/ 194


Complexité des algorithmes
Méthodologie des spécifications
Structures de données
Algorithmes de recherche

Les arbres généraux ordonnés (étiquetés)

Une forêt est une liste d’arbres.


Si le nombre de fils (resp. sous-arbres) d’un nœud est n alors
le premier fils (resp. sous-arbre) est le fils (resp. sous-arbre)
gauche et le nème fils (resp. sous-arbre) est le fils (resp.
sous-arbre) droit.
Le bord gauche (resp. droit) d’un arbre est le chemin obtenu
en ne parcourant que les fils gauches (resp. droits) à partir de
la racine.

Béatrice Duval & Igor Stéphan SDA 73/ 194


Complexité des algorithmes
Méthodologie des spécifications
Structures de données
Algorithmes de recherche

Spécification des arbres généraux ordonnés

specification AGO0 (E )
etend BASE(E ), LISTE(AGO(E ))

sortes AGO, ForetaliasListe(AGO(E ))

operations
Λ : AGO(E )
noeud : E × Foret → AGO(E )
racine : AGO(E ) → E
sous arbres : AGO(E ) → Foret
neme : AGO(E ) × Nat → AGO(E )
vide ? : AGO(E ) → Bool

Béatrice Duval & Igor Stéphan SDA 74/ 194


Complexité des algorithmes
Méthodologie des spécifications
Structures de données
Algorithmes de recherche

suite de AGO0

preconditions {a : AGO(E ); n : Nat}


pre racine(a) : ¬(vide ?(a))
pre sous arbres(a) : ¬(vide ?(a))
pré neme(a, n) : ¬(vide ?(a))
et (n ≤ longueur (sous arbres(a)))
axiomes {n : Nat; f : Foret; x : E }
ago(0) : sous arbres(noeud(x, f )) = f
ago(1) : neme(noeud(x, f ), n) = ieme(f , n)
ago(2) : racine(noeud(x, f )) = x
ago(3) : vide ?(Λ) = vrai
ago(4) : vide ?(noeud(x, f )) = faux

Béatrice Duval & Igor Stéphan SDA 75/ 194


Complexité des algorithmes
Méthodologie des spécifications
Structures de données
Algorithmes de recherche

Occurrence de nœud
L’occurrence de nœud est un codage qui permet une
représentation en liste d’un arbre.
A la racine de l’arbre est associé le mot vide.
Si µ est l’occurrence associée à un nœud alors l’occurrence de
son nème fils est µ.(n − 1).
n1

n2 n3 n5

n8 n4 n6 n7

n9 n10 n11

{(ǫ, n1), (0, n2), (1, n3), (2, n5), (00, n8), (10, n4),
(20, n6), (21, n7), (210, n9), (211, n10), (212, n11)}
Béatrice Duval & Igor Stéphan SDA 76/ 194
Complexité des algorithmes
Méthodologie des spécifications
Structures de données
Algorithmes de recherche

Ordre hiérarchique et parcours en largeur d’abord

La numérotation en ordre hiérarchique numérote à partir de la


racine en ordre croissant et niveau par niveau.
n1

n2 n3 n4

n5 n6 n7 n8

n9 n10 n11

Le parcours d’un arbre consiste à inspecter tour à tour tous les


nœuds.
Le parcours en largeur d’abord explore les nœuds dans l’ordre
hiérarchique.

Béatrice Duval & Igor Stéphan SDA 77/ 194


Complexité des algorithmes
Méthodologie des spécifications
Structures de données
Algorithmes de recherche

Les arbres binaires (ordonnés étiquetés)

Un nœud d’arbre binaire (ordonné étiqueté)


< , , > est un nœud tel que la liste des sous-arbres est
remplacé par une paire.
L’ordre des arbres binaires portent non seulement sur les fils
entre-eux mais aussi des fils par rapport au père, ce qui induit
une anti-symétrie.
n1 n1

n2 n3 n2 n3

n4 n4

Les deux arbres binaires ci-dessus ne sont pas égaux :


< n1, < n2, Λ, Λ >, < n3 , < n4 , Λ, Λ >, Λ >>=
< n1, < n2, Λ, Λ >, < n3 , Λ, < n4 , Λ, Λ >>>

Béatrice Duval & Igor Stéphan SDA 78/ 194


Complexité des algorithmes
Méthodologie des spécifications
Structures de données
Algorithmes de recherche

Spécification des arbres binaires

specification AB0 (E )
etend BASE(E )

sortes ArBin

operations
Λ : ArBin(E )
< , , >: E × ArBin(E ) × ArBin(E )
→ ArBin(E )
racine : ArBin(E ) → E
g : ArBin(E ) → ArBin(E )
d : ArBin(E ) → ArBin(E )
vide ? : ArBin(E ) → Bool

Béatrice Duval & Igor Stéphan SDA 79/ 194


Complexité des algorithmes
Méthodologie des spécifications
Structures de données
Algorithmes de recherche

suite de AB0

preconditions {a : ArBin(E )}
pre g (a) : ¬(vide ?(a))
pre d(a) : ¬(vide ?(a))
pre racine(a) : ¬(vide ?(a))
axiomes {a, ag , ad : ArBin(E ); x : E }
ab(0) : g (< x, ag , ad >) = ag
ab(1) : d(< x, ag , ad >) = ad
ab(2) : racine(< x, ag , ad >) = x
ab(3) : vide ?(Λ) = vrai
ab(4) : vide ?(< x, ag , ad >) = faux

Béatrice Duval & Igor Stéphan SDA 80/ 194


Complexité des algorithmes
Méthodologie des spécifications
Structures de données
Algorithmes de recherche

Termes et arbres

Un arbre binaire est représenté par un terme qui est un arbre


ternaire.
< , , >

n1
n1 < , , > < , , >

n2 n3
n2 Λ Λ n3 < , , > Λ

n4
n4 Λ Λ

< n1, < n2, Λ, Λ >, < n3 , < n4 , Λ, Λ >, Λ >>

Béatrice Duval & Igor Stéphan SDA 81/ 194


Complexité des algorithmes
Méthodologie des spécifications
Structures de données
Algorithmes de recherche

Arbres binaires particuliers

Un arbre binaire est dégénéré si


tout nœud n’a au plus qu’un fils.

Un arbre binaire est com-


plet si chaque niveau est
complètement rempli.

Un arbre binaire est localement


complet si tout nœud interne a
exactement deux fils.

Béatrice Duval & Igor Stéphan SDA 82/ 194


Complexité des algorithmes
Méthodologie des spécifications
Structures de données
Algorithmes de recherche

Un arbre binaire est par-


fait si tous les niveaux sont
complètement remplis sauf le
dernier mais tous les nœuds du
dernier niveau sont groupés à
gauche.
Un peigne à gauche (resp. à
droite) est un arbre binaire lo-
calement complet dont tous les
fils droits (resp. gauches) sont
des feuilles.

Béatrice Duval & Igor Stéphan SDA 83/ 194


Complexité des algorithmes
Méthodologie des spécifications
Structures de données
Algorithmes de recherche

Occurrence et ordre hiérarchique


Dans un arbre binaire, si un nœud a pour occurrence, µ son
fils gauche (resp. droit) a pour occurrence µ0 (resp. µ1).
ε

0 1

00 01 10 11

000 001010
Si l’arbre est parfait, i la numérotation en ordre hiérarchique
et µ l’occurrence d’un nœud alors
m = i − 2⌊log2 i⌋ , µ représentation binaire de m ;
son fils gauche (resp. droit) a pour numérotation en ordre
hiérarchique 2i (resp. 2i + 1).
Béatrice Duval & Igor Stéphan SDA 84/ 194
Complexité des algorithmes
Méthodologie des spécifications
Structures de données
Algorithmes de recherche

Propriétés des arbres binaires

Pour tout arbre binaire non vide ayant n nœuds et une


hauteur h, ⌊log2 n⌋ ≤ h ≤ n − 1.
Pour tout arbre binaire non vide ayant n nœuds et f feuilles,
f ≤ n+1
2 .
Tout arbre binaire localement complet ayant n nœuds internes
a (n + 1) feuilles.
La hauteur d’un arbre binaire localement complet ayant n
feuilles est ⌈log2 n⌉.

Béatrice Duval & Igor Stéphan SDA 85/ 194


Complexité des algorithmes
Méthodologie des spécifications
Structures de données
Algorithmes de recherche

La binarisation des arbres généraux

Tout arbre général est représentable sous la forme d’un arbre


binaire.
La binarisation transforme le premier fils d’un arbre général en
fils gauche et tout nème fils (n > 1) en fils droit du n − 1ème
fils.
n1 n1

n2 n3 n4 n2

n5 n6 n7 n5 n3

n6 n4

n7

Béatrice Duval & Igor Stéphan SDA 86/ 194


Complexité des algorithmes
Méthodologie des spécifications
Structures de données
Algorithmes de recherche

Spécification de la binarisation

specification BINARISATION(E )
etend AGO(E ), AB(E )
operations
binarisation : AGO(E ) → ArBin(E )
bin : Liste(AGO(E )) → ArBin(E )
axiomes {a : AGO(E ); f : Foret}
bin(0) : binarisation(a) =
si vide ?(a) alors Λ sinon bin(cons(a, [ ])) fsi
bin(1) : bin(f ) =
si vide ?(f ) alors Λ
sinon < racine(tete(f )), bin(sous arbres(tete(f ))),
bin(fin(f )) > fsi

Béatrice Duval & Igor Stéphan SDA 87/ 194


Complexité des algorithmes
Méthodologie des spécifications
Structures de données
Algorithmes de recherche

Parcours en profondeur d’abord


Le parcours en profondeur suit les liens père-fils pour explorer
l’arbre.
n1

n2 n6

n3 n4 n7 Λ

Λ Λ n5 Λ Λ n8

Λ Λ Λ Λ

Béatrice Duval & Igor Stéphan SDA 88/ 194


Complexité des algorithmes
Méthodologie des spécifications
Structures de données
Algorithmes de recherche

Le parcours en profondeur main gauche (resp. main droite) choisit


d’explorer systématiquement le fils gauche (resp. droit) et ses
descendants, avant le fils droit (resp. gauche) et ses descendants.
n1

n2 n6

n3 n4 n7 Λ

Λ Λ n5 Λ Λ n8

Λ Λ Λ Λ

Béatrice Duval & Igor Stéphan SDA 89/ 194


Complexité des algorithmes
Méthodologie des spécifications
Structures de données
Algorithmes de recherche

Les ordres de parcours


Un nœud lors d’un parcours en profondeur (main gauche) est
rencontré trois fois : à la descente du père ; ordre préfixe ;

n1

n2 n6

n3 n4 n7 Λ
(n1 n2 n3 n4 n5 n6 n7 n8)
Λ Λ n5 Λ Λ n8

Λ Λ Λ Λ

opr é(a) = si vide ?(a) alors [ ] sinon


cons(racine(a), conc(opr é(g (a)), opr é(d(a)))) fsi

Béatrice Duval & Igor Stéphan SDA 90/ 194


Complexité des algorithmes
Méthodologie des spécifications
Structures de données
Algorithmes de recherche

Les ordres de parcours


Un nœud lors d’un parcours en profondeur (main gauche) est
rencontré trois fois : entre la remontée du fils gauche et la descente
sur le fils droit ; ordre infixe ;

n1

n2 n6

n3 n4 n7 Λ
(n3 n2 n5 n4 n1 n7 n8 n6)
Λ Λ n5 Λ Λ n8

Λ Λ Λ Λ

oinf (a) = si vide ?(a) alors [ ] sinon


conc(oinf (g (a)), cons(racine(a), oinf (d(a)))) fsi
Béatrice Duval & Igor Stéphan SDA 91/ 194
Complexité des algorithmes
Méthodologie des spécifications
Structures de données
Algorithmes de recherche

Les ordres de parcours


Un nœud lors d’un parcours en profondeur (main gauche) est
rencontré trois fois : à la remontée du fils droit : ordre postfixe.

n
n1

n2 n6

n3 n4 n7 Λ
(n3 n5 n4 n2 n8 n7 n6 n1)
Λ Λ n5 Λ Λ n8

Λ Λ Λ Λ

opos(a) = si vide ?(a) alors [ ] sinon


conc(opos(g (a)), conc(opos(d(a)), singleton(racine(a)))) fsi

Béatrice Duval & Igor Stéphan SDA 92/ 194