Chapitre VII. Tri
Tri par tas
Tri rapide
Tris faisant appel aux arbres
• Dichotomique (quick sort)• Tri par fusion • Tris par tas • ….
Tri par tas
• Fait appel à la structure de l’arbre binaire parfait partiellement ordonné
• La complexité est • Le principe : prendre le tri par sélection et
accélérer la recherche de min par l’organisation adéquate de données
• (heapsort)
nn lg,
Rappel du tri par sélection
Tri par sélection
• Principe : on recherche le minimum dans la partie restante du tableau et on l’échange avec l’élément qui suit la partie déjà triée.
• Après k placements les k plus petits éléments du tableau sont déjà à leur place définitive
G
Arbre binaire parfait• Arbre binaire parfait : tous les niveaux sont complètement remplis, sauf
éventuellement le dernier niveau. Dans ce dernier cas les nœuds (feuilles) du dernier niveau sont groupés le plus à gauche possible. Arbre binaire parfait est un arbre équilibréparfait « imparfait »
Numérotation hiérarchique(1)
• Numéroter en ordre croissant à partir de 1 tous les nœuds• num(r)=1• num(n)=i => num(FG(n))=2i et num(FD(n))=2i+1
1
32
4 56 7
8 9 10
Numérotation hiérarchique(2)
• 2 < i < n => le père du noeud d’indice i
est à l’indice (i div 2)
• 1 < i < (n div 2) => le fils gauche du nœud d’indice i
est en 2i
le fils droit du nœud d’indice i
est en 2i+1
a b c d e f g h i j
Représentation sous forme d’un tableau
• Codage d’un arbre binaire parfait avec N nœuds par un tableau de N cases
• Un arbre binaire parfait comportant p nœuds et de hauteur
1 a
3 c2 b
4 d 5 e 6 f 7 g
8 h 9 i 10 j
1 2 3 4 5 6 7 8 9 10
p2log
Arbres binaires parfaits partiellement ordonnés
• ABPPO : est un arbre étiqueté par des éléments d’un ensemble muni d’un ordre total ( ex < sur un ensemble des entiers).
• contenu(n)<contenu(fils(n)) pour tout noeud n et pour tout fils(n)
(1;3)
(3,9)(2;5)
(4;6) (5;7) (6;11) (7; 10)
(8; 12) (9;18) (10;13)
Ex. Arbre binaire parfait partiellement ordonné.
Notation : (index, contenu)
Tas
• Tas : un tableau représentant un arbre parfait partiellement ordonné.
- t[1] est la racine
- t[i div 2] est le père de t[i] pour tout i>1
- t[2*i] = FG(t[i]) (si il existe)
- t[2*i +1] = FD(t[i]) (si il existe)
- Si p est le nombre de nœuds de l’arbre et si 2*i=p, alors t[i] n’a qu’un seul fils t[p].
- Si i est supérieur à p div 2, t[i] est une feuille
Si M est la taille du tableau qui contient un tas de p éléments, alors p<M
(1) Adjonction d’un élément :
- ajouter le nouvel élément à la nouvelle feuille créée à cet effet
- réorganiser le tas pour maintenir la cohérence
Ajout (1)
(1;3)
(3,9)(2;5)
(4;6) (5;7) (6;11) (7; 10)
(8; 12) (9;18) (10;13) (11;4)
(1;3)
(3,9)(2;5)
(4;6) (5;4) (6;11) (7; 10)
(8; 12) (9;18) (10;13) (11;7)
1
Ajout (2)
(1;3)
(3,9)(2;5)
(4;6) (5;4) (6;11) (7; 10)
(8; 12) (9;18) (10;13) (11;7)
(1;3)
(3,9)(2;4)
(4;6) (5;5) (6;11) (7; 10)
(8; 12) (9;18) (10;13) (11;7)
(2)
Ajout (3)
Procédure Ajouter(réf t: tableau[1..M] d’entiers; réf p:entier, x:entier);{on suppose que p<M lors de l’appel – pas de vérification du débordement}
Var i : entier;
Début
{une nouvelle feuille est crée et x est placé dedans}
p:=p+1; t[p]:=x; i:=p;
{conformité à la définition : on effectue les échanges tant que x est inférieur à son père}
Tq (i>1) et (t[i]<t[i div 2]) faire
échanger(t[i]), t[i div 2]);
i:=i div 2
FTq
Fin Ajouter
Suppression (1)
(2) Suppression de l’élément minimal :
- retirer le min et le renvoyer ;
- réorganiser le tas : placer la dernière feuille dans la racine et réordonner l’arbre : pour chaque nœud chercher le plut petit de ces deux fils et permuter.
Suppression (2)
(1;3)
(3,9)(2;4)
(4;6) (5;5) (6;11) (7; 10)
(8; 12) (9;18) (10;13) (11;7)
(3)
(3,9)(2;4)
(4;6) (5;5) (6;11) (7; 10)
(8; 12) (9;18) (10;13) (11;7)
Suppression (3)
(1;7)
(3,9)(2;4)
(4;6) (5;5) (6;11) (7; 10)
(8; 12) (9;18) (10;13)
(1;4)
(3,9)(2;7)
(4;6) (5;5) (6;11) (7; 10)
(8; 12) (9;18) (10;13)
Suppression (4)
(1;4)
(3,9)(2;5)
(4;6) (5;7) (6;11) (7; 10)
(8; 12) (9;18) (10;13)
Suppression (5)Procédure SuppressionMin(réf t: tableau [1…M] d’entiers, réf p,min : entiers){on suppose que le tas n’est pas vide au moment de l’appel : p>0}Var i,j: entiers;Début { on retient le minimum} min:=t[1]; {réorganisation du tas} t[1]:=t[p]; p:=p-1; i:=1; {placer la dernière feuille à la racine} Tq i< (p div 2) faire {t[i] – n’est pas une feuille} { calcul de l’indice du plus petit des deux fils de t[i] ou de son seul fils 2*i=p} Si (2*i=p) ou (t[2*i]<t[2*i+1])
alors j:=2*i sinon j:=2*i +1FSiSi t[i] > t[j] {échange si la condition d’ordre n’est âs satisfaite} alors échanger(t[i], t[j]) i:=j; sinon sortir FSiFTq
FinSuppressionMin;
Utilisation d’un tas pour le tri d’un tableau (1)
• La base : le tri par sélection. Rechercher le minimum dans la partie du tableau non-triée et le placer à sa place définitive.
• Transformer le tableau en tas (avec la procédure « ajouter »)
• Utiliser le tas pour extraire le min et le placer à l afin du tableau
• (tri par ordre décroissant)
min
1 M
Tas de M éléments
min
1 M-1
Tas de M -1 éléments
Etc…
Utilisation d’un tas pour le tri d’un tableau (2)
Procédure Tri-par-Tas(réf t: tableau[1…M] d’entiers)Var p, min: entiers
Début
p:=0
Tq p<M faire {construction du tas}
ajouter(t,p,t[p+1]);
{p augmente de 1 à chaque appel de « ajouter »}
FTq
Tq p>1 faire
SuppressionMin(t,p,min)
{p diminue de 1 à chaque appel SuppressionMin}
t[p+1]:=min
FTq
Fin Tri-par-Tas
Complexité du tri pas tas
• Construction du tas : M appels de la procédure ajouter. Sa complexité dans le pire de cas est de
• La sélection de l’élément le plus petit se fait par M-1 appels de la procédure SuppressionMin. Sa complexité dans le pire des cas est de
• La complexité du tri par tas est donc en • Avec « comparaison » comme opération fondamentale.
M2log
M2log
MM 2log
Tri rapide(Quick Sort)
• Tri dichotomique : on partage une liste à trier ( tableau) en deux sous-listes L1,L2:
• Les éléments de L1 sont tous inférieurs à tous les éléments de L2
• On recommence jusqu’à avoir les sous-listes réduits à un élément
Principe de tri rapide
Élément Pivot
Choisir un élément pivot et placer les éléments inférieurs à gauche, supérieurs – à - droite
Pivot se trouve à sa place définitive
Choix du Pivot – 1er élément du tableau
Recommencer avec les deux sous-listes tq atteindre 1 élément
Exemple
• 101 212 21 123 47 79 195
• 47 79 21 101 123 212 195
• 21 47 79 101 123 212 195• • 21 47 79 101 123 212 195
• 21 47 79 101 123 195 212
Tri rapide – pivot
• Supposons que nous avons une procédure placer (réf t,val i,j,réf k):
• t est défini entre i, j,• k – emplacement définitif du pivot
(paramètre de sortie)• placer : place élément t[i] à la k-ème place
et renvoie k.
Algorithme général
• Procédure tri-rapide(réf t: tableau[1..n+1] des entiers; val i,j : entiers)
• {t[n+1] contint une sentinelle}• Var k : entier;• Début
– Si i<j alors {plus qu’un élément dans le sous-tableau}– Placer(t,i,j,k) {partitionner t selon le principe du pivot et placer
t[i] en k}– Tri-rapide(t,i,k-1)– Tri-rapide(t,k+1,j)– Fsi
Fin Tri-rapide
L’appel tri-rapide(t,1,n) provoque le tri du tableau complet
Procédure de partition et de placement(1)
G D
Avancer G Tq t[G] < Pivot
Reculer D Tq t[D] > Pivot
Permuter
G D
Procédure de partition et de placement(2)
• Ajout d’une sentinelle t[n+1] > t[i] pour tout i=1, ….,n
• Quand on appelle « placer » sur une partie de tableau qui n’est pas la fin du tableau, cette sentinelle existe : l’élément qui se trouve à l’indice j+1 est le pivot de l’appel précédent. Il est donc supérieur à tous les éléments entre i et j.
Procédure de partition et de placement(3)
• Procédure placer (réf t: tableau[1..n+1] des entiers; i,j, : entiers, réf k: entier)
• Var G : entier;• Début
– G:=i+1;k:=j– TQ G<k faire {Le pivot est t[i]
• TQ t[k] >t[i] k:=k-1;• TQ t[G] < t[i] G:=G+1;• Si G<K alors• échanger(t [G], t[k])• G:=G+1• k:=k-1FTQÉchanger(t[i], t[k])
Fin placer
Analyse
• Graphe d’appels est un arbre binaire• Complexité au pire• Opération fondamentale : comparaison.• A chaque niveau de l’arbre au pire n
comparaisons• La hauteur de l’arbre est
• C est donc (?)
n2log
Version itérative• Procédure tri-rapide-iter(réf t : tableau[1..n+1]des entiers)• Var Q:PILE; i,j,k : entiers• i:=1;j:=n;pile-vide(Q);• TQ vrai faire• TQ i<j faire• placer(t,i,j,k) emplilerQ5i,j,k);j:=k-1• FTQ• Si non estèvide(Q) alors• (i,j,k):=sommet(Q); dépiler(Q);i:=k+1• sinon• sortir• FSIFTQFintri-rapide_iter