Structures de Données
et Complexité
Maximier – Tri Arbre
N.E. Oussous
FIL – USTL
SDC - Licence – p.1/32
Maximier - Définition
Un arbre vide est considéré comme un maximier.
Un arbre binaire non vide est un maximier si et seulement si
sa racine porte la valeur maximale.
ses sous-arbres principaux sont des maximiers.
À la racine des sous-arbres principaux on trouve donc les ème et
ème valeurs selon l’ordre décroissant.
On a un ordre partiel :
Le père est plus grand que ses deux fils.
Pas d’ordre entre les frères.
SDC - Licence – p.2/32
Maximier - Exemple
23216
5736
7 8
9
SDC - Licence – p.3/32
Maximier - Utilité
La structure de maximier n’est pas utilisée pour implémenter les
primitives usuelles (recherche, insertion, suppression) sur les
ensembles.
Par exemple, la recherche d’une valeur particulière peut amener à
parcourir tout l’arbre (donc être en ).
Elle nécessite de plus la gestion d’une pile dont la hauteur est celle
de l’arbre lui-même.
Cette recherche serait donc inefficace.
Un maximier est par contre utilisé pour extraire le maximum parmi
un ensemble de valeurs.
SDC - Licence – p.4/32
Maximier - Cueillette
La suppression de l’élément maximal est, par contre, plus efficace.
On remplace cet élément par le plus grand de ses successeurs.
On recommence l’opération avec le successeur utilisé.
On supprime la feuille utilisée en dernier.
23216
5736
7 8
9
2 3 2 1
536
7
8
7
6
SDC - Licence – p.5/32
Cueillette - Code
procedure Supprimer_Max(var T : Maximier) ;
X : Curseur ;
Begin
X := Racine(T) ;
While not Est_Feuille(X) Do Begin
Determiner quel successeur possède
la valeur maximale ;
Recopier cette valeur;
Descendre X du coté où se trouvait
la valeur maximale ;
end ; // while
Supprimer(X);
End ; // Supprimer_Max
SDC - Licence – p.6/32
Pré-Maximier
Un Pré-Maximier est un arbre dont les sous-arbres principaux sont
des maximiers.
Un pré-maximier n’est pas nécessairement un maximier, cela
dépend de la valeur portée à la racine.
La transformation en maximier (Réorganisation) se fait par
une méthode analogue à celle utilisée pour la suppression du
maximum.
SDC - Licence – p.7/32
Pré-Maximier Maximier
Si le pré-maximier n’est pas un maximier, il faut
Échanger la valeur portée à la racine avec la valeur maximale de
ses successeurs,
Réorganiser le successeur avec lequel a eu lieu l’échange.
La réorganisation nécessite le parcours d’une seule branche, avec un
traitement en à chaque nœud parcouru.
SDC - Licence – p.8/32
Réorganisation - Exemple
3 2 1 6
573
8
2
6
7
9
3 2 1 6
573
8
9
7
2
6
SDC - Licence – p.9/32
Réorganisation - Code
procedure Reorganiser(var T : Maximier) ;
X : Curseur ;
Begin
X := Racine(T) ;
Repeat
if not Est_Vide(sag(X)) then begin
G := X; G := sag(G) ;
if not Est_Vide(sad(X)) then begin
D := X; D := sad(D) ;
if Valeur(D) > Valeur(G) and Valeur(D) > Valeur(X) then begin
Changer_Valeur(X, Valeur(D)); X := D;
end else
if Valeur(G) > Valeur(D) and Valeur(G) > Valeur(X) then begin
Changer_Valeur(X, Valeur(G)); X := G;
end else exit;
end else begin
Changer_Valeur(X, Valeur(G)); X := G;
end;
end else
if not Est_Vide(sad(X)) then begin
Changer_Valeur(X, Valeur(D)); X := D;
end else exit;
until false ;// Repeat
End ;
SDC - Licence – p.10/32
Fabrication d’un maximier
Un arbre binaire quelconque contient des maximiers : toutes ses
feuilles.
Les sous-arbres de hauteur sont donc des pré-maximiers.
Par réorganisations successives, on peut transformer tous les
sous-arbres de hauteur en maximiers, puis ceux de hauteur , etc
Il faudra donc parcourir les sous-arbres par hauteurs croissantes (les
sous-arbres les plus profonds en premier).
SDC - Licence – p.11/32
Fabrication - Exemple
3 2
576
9
2
7
1
3
6
8 3 2
53
1
8
7
6
9
7
6
2
SDC - Licence – p.12/32
Fabrication - Code récursif
Cet algorithme s’exprime facilement de façon récursive
procedure Fabriquer_maximier(C : Curseur)
Begin
if not Est_Vide(sag(X)) then begin
G := X; G := sag(G) ;
Fabriquer_maximier(G) ;
end; // if
if not Est_Vide(sad(X)) then begin
D := X; D := sad(D) ;
Fabriquer_maximier(D);
end; // if
// on a maintenant un pré-maximier
Reorganiser(C);
End ; // Fabriquer_maximier
SDC - Licence – p.13/32
Fabrication - Code itératif
Cet algorithme peut aussi s’exprimer (informellement) de façon itérative
par
for h := 2 to hauteur(arbre) do begin
Réorganiser tous les sous-arbres de hauteur h ;
end; // for
Mais l’interface d’arbre proposée jusqu’ici ne permet
pas d’implémenter aisément cette version itérative,
faute de moyen efficace pour parcourir tous les
sous-arbres d’une hauteur donnée.
SDC - Licence – p.14/32
Tri-Arbre : Heapsort
L’utilisation des maximiers peut amener à une méthode de tri appelée
Tri-arbre ou Heapsort.
Description informelle de l’algorithme :
Tri_Arbre(var T : Tableau)
Begin
Constituer un arbre contenant les valeurs de T;
Fabriquer un maximier à partir de cet arbre;
for i:=low(T) to high(T) do begin
Ranger le maximum dans T[i] ;
Retirer le maximum de l’arbre ;
end;// for
End ;// Tri_Arbre
En pratique, cette méthode de tri est employée dans le
cas d’une implémentation d’arbre bien particulière : le tas.
SDC - Licence – p.15/32
La structure de Tas
La structure de tas permet de représenter, dans un tableau, un arbre
quasi-équilibré, dont les feuilles à profondeur maximale sont situées
le plus à gauche possible.
Elle consiste à ranger les valeurs portées par les nœuds
par profondeur croissante
de gauche à droite (pour une profondeur donnée).
un arbre = un tableau
un curseur = un indice du tableau
un nœud = une case du tableau
SDC - Licence – p.16/32
Tas - Exemple
23216
5736
7 8
9
897 637523216
1 2 3 4 5 6 7 8 9 10 11 12
SDC - Licence – p.17/32
Tas dans 1 tableau d’indices 1..n
T(8) T(9) T(10) T(11) T(12)
T(4) T(5) T(6) T(7)
T(2) T(3)
T(1)
Racine
Successeur gauche
Successeur droite
Prédecesseur
Est_Feuille
Possède 2 successeurs
Possède 1 seul successeur
Dernier nœud interne
SDC - Licence – p.18/32
Tas - Cas général
T[high(T)]............
T[low(T)+3] T[low(T)+4] T[low(T)+5] T[low(T)+6]
T[low(T)+1] T[low(T)+2]
T[low(T)]
Racine
Successeur gauche
Successeur droite
Prédecesseur
Est_Feuille
Possède 2 successeurs
Possède 1 seul successeur
Dernier nœud interne
SDC - Licence – p.19/32
La structure de Tas
Les moins
Les arbres auront une taille maximale, celle du tableau.
Un nœud est associé à une case (fixée) du tableau.
Les plus
Pas besoin de pointeurs.
Le passage d’un nœud à ses successeurs se fait par adressage
calculé.
Possibilité de calculer également l’emplacement du
prédécesseur.
Possibilité de parcourir l’arbre de bas en haut.
SDC - Licence – p.20/32
Réorganiser un Tas : Itératif
procedure Reorganiser( C : Curseur ) ;
I : Curseur ;
begin
I := C ;
repeat
if Possede_2_Successeurs(I) then begin
if T[sag(I)] > T[sad(I)] and T[sag(I)] > T[I] then begin
Echanger(T[I],T[sag(I)]);
I := sag(I);
end else
if T[sad(I)] > T[sag(I)] and T[sad(I)] > T[I] then begin
Echanger(T[I],T[sad(I)]);
I := sad(I);
end else // T[I] est la plus grande des 3 valeurs
exit;
end else
if Possede_1_Seul_Successeur(I) and T[sag(I)]>T[I] then begin
Echanger(T[I],T[sag(I)]);
exit;
end else exit;
Until false ;
end; // Reorganiser
SDC - Licence – p.21/32
Réorganiser un Tas : Récursif
Reorganiser(T, C)
g : Curseur ;
d : Curseur ;
Begin
g := sag(C) ;
d := sad(C) ;
// on détermine max(T[C], T[g], T[d])
if g <= high(T) and T[g] > T[C] then
max := g
else
max := C ;
if d <= high(T) and T[d] > T[max] then max := d ;
if max <> C then begin // c’est un pré-maximier
Echanger(T[C], T[max]) ;
Reorganiser(T, max) ;
end; // if
End; // Reorganiser
SDC - Licence – p.22/32
Réorganiser Tas : Complexité
Le temps d’exécution de Reorganiser sur un sous-arbre de taille
enraciné en un nœud iest la somme du temps et le temps
d’exécution de Reorganiser sur un sous-arbre enraciné sur l’un
des deux fils du nœud i.
Les sous-arbres des fils ont chacun une taille au plus égale à .
Le pire des cas est atteint lorsque le dernier niveau est rempli
exactement à moitié.
SDC - Licence – p.23/32
Réorganiser Tas : Complexité
On aboutit à la relation de récurrence suivante :
On est dans le cas 2 du théorème général avec
Ainsi et
La solution est donc
SDC - Licence – p.24/32
Fabriquer un Tas
Les feuilles sont situées dans les dernières cases du tableau :
T[( +1)..n].
On parcourt les sous-arbres par hauteurs croissantes en parcourant
les cases du tableau en ordre inverse.
procedure Fabriquer_Tas(var T : Arbre) ;
begin
for i:=Dernier_arbre_h2 downto Racine do begin
Reorganiser(i); // Reorganiser(T,i)
end;
end Fabriquer_Tas;
Le temps d’exécution de Fabriquer_tas : Chaque appel à
Reorganiser coûte . Il existe appels de ce
type. Donc, le temps d’exécution est au plus .
SDC - Licence – p.25/32
Exemple
Soit le tableau suivant :
12345678910
4 1 3 2 16 9 10 14 8 7
Il lui correspond l’arbre suivant :
1
2 3
4 5 6 7
8 9 10
14 8 7
162
1
9 10
3
4
SDC - Licence – p.26/32
Exemple
1
2 3
4 5 6 7
8 9 10
14 8 7
162
1
9 10
3
4
1
2 3
4 5 6 7
8 9 10
9
2
10
37
1
16
14
8
4
SDC - Licence – p.27/32
Fabriquer Tas : Complexité
Une analyse plus fine est basée sur les propriétés des tas :
La hauteur d’un tas à éléments est .
sous-arbres de hauteur .
Le temps de calcul de Reorganiser sur un nœud de hauteur est
.
Le coût total pour Fabriquer_tas sera
SDC - Licence – p.28/32
Fabriquer Tas : Complexité
On a l’égalité :
Donc, le temps d’exécution de Fabriquer_tas peut être borné
par
Ainsi, on peut construire un tas à partir d’un tableau non ordonné en
un temps linéaire.
SDC - Licence – p.29/32
Le tri par tas : Heapsort
On construit un tas par Fabriquer_Tas à partir de T[1..n],
n=length(T).
L’élément maximum de Tse trouve à la racine T[1].
On le place à sa position finale en l’échangeant avec T[n].
On décrémente la taille du tableau en ne considérant que le
sous-tableau T[1..(n-1)].
On transforme T[1..(n-1)] en tas puisque les fils de la racine
restent des tas. Il y aura éventuellement à descendre la nouvelle
racine à sa place.
SDC - Licence – p.30/32
1 / 6 100%
La catégorie de ce document est-elle correcte?
Merci pour votre participation!

Faire une suggestion

Avez-vous trouvé des erreurs dans linterface ou les textes ? Ou savez-vous comment améliorer linterface utilisateur de StudyLib ? Nhésitez pas à envoyer vos suggestions. Cest très important pour nous !