Vous êtes sur la page 1sur 76

ALGORITHMIQUE &

STRUCTURES DE DONNÉES
1er Année Cycle Préparatoire | MPI

06/12/2022 1
Plan

VI. Les algorithmes de Tri


1. Le problème du tri : Introduction
2. Tri par Sélection
3. Tri par insertion
4. Tri à Bulles
5. Tri par Dénombrement
6. Tri GNOME
7. Tri Fusion
8. Tri Rapide
9. La classification des algorithmes de tri

06/12/2022 2
Algorithmique &
Structures de Données

LES ALGORITHMES DE TRI


1er Année Cycle Préparatoire | MPI

06/12/2022 3
Le problème du tri

On désigne par Tri l'opération consistant à ordonner un ensemble d'éléments


en fonction de clés sur lesquelles est définie une relation d'ordre.
Les algorithmes de tri ont une grande importance pratique. ils sont
fondamentaux dans certains domaines, comme l'informatique de gestion où
l'on tri de manière quasi-systématique des données avant de les utiliser.
L'étude du tri est également intéressante en elle-même car il s'agit sans
doute du domaine de l'algorithmique qui a été le plus étudié et qui a conduit à
des résultats remarquables sur la construction d'algorithmes et l'étude de leur
complexité.

4
Le problème du tri

Principe de fonctionnement
On distingue les algorithmes procédant par comparaisons successives entre
éléments, dits « tris par comparaisons ».
Les algorithmes de tri par comparaison lisent les entrées uniquement au
moyen d'une fonction de comparaison binaire ou ternaire (lorsque le cas
d'égalité est traité différemment). Il existe encore différents principes de
fonctionnement au sein de cette classe : certains algorithmes de tri par
comparaison procèdent par insertions successives, d'autres par fusions,
d'autres encore par sélection.
En l'absence de précisions, on entend habituellement par « algorithme de tri »
un algorithme de tri procédant par comparaisons.

5
Le problème du tri

Ranger des éléments selon un ordre ↗ ou ↘

• Algorithmes élémentaires :
tri à bulles, tri par sélection, tri par insertion, …
• Algorithmes complexes :
tri rapide (Quicksort), tri par tas (Heapsort), …

Le choix de la méthode de tri dépend fortement :


• du volume de données à trier
• du type des éléments à trier

6
TRI PAR SELECTION
Algorithmes élémentaires
Tri par Sélection

Sans le savoir, où sans s’en rendre compte, on est confronté très jeune à des
algorithmes de tri.
je dirais que cela se produit au plus tard en classe de primaire, vers l’âge de six
ans, à l’occasion du passage du photographe scolaire.
Pour bien composer sa photo, le photographe doit placer les enfants sur le
banc en fonction de leurs tailles.

8
Tri par Sélection

Pour cela, le photographe passe en revue les enfants à la recherche du plus


petit. Une fois trouvé, il le place sur le banc.
il réitère cette opération sur les enfants restant en plaçant à chaque fois
l’enfant sélectionné à la prochaine place disponible sur le banc.
L’algorithme se termine lorsqu’il ne reste plus d’enfant. Si vous avez bien
suivi, vous aurez compris que le dernier enfant à être sélectionné, et donc à
être placé sur le banc, est mécaniquement le plus grand.

9
Tri par Sélection
Tri par Sélection


Tri par Sélection

Tri_Selection

Début
Pour Chaque Elément de T faire
Chercher le Min de la position i
Si il ∃ un j < i permutation (i,j)
Fpour
Fin
Tri par Sélection

Tri_Selection(var T : tab; N : entier)


VAR i, j, pmin : entier
temp : entier
Début
Pour i de 1 à N-1 faire
pmin := i
pour j de i+1 à N faire
Si T[j] < T[pmin] Alors
pmin := j
fsi
fpour
Si i <> pmin Alors
temp := T[i]
T[i] := T[pmin]
T[pmin] := temp
fsi
Fpour
Fin
Tri par Sélection : variante 1

Tri Min Max


L'idée est :
de chercher simultanément le minimum et le
maximum,
d'échanger le minimum avec le premier élément
d'échanger le maximum avec le dernier élément
Tri par Sélection : variante 1

Tri Min Max

Tri_Min_Max

Début
Chercher le Min de la position d
Chercher le Max de la position f
Si il ∃ un Min < d permutation (d,Min)
Si il ∃ un Max > f permutation (f,Max)
Fsi
Tri par Sélection : variante 1

Tri Min Max


Version itérative
Tri_Min_Max(var T : tab; N : entier)
VAR i, j, pmin, temp : entier

Début
d := 1; f := N
Tant que d < f faire
min_max(T,d,f,pmin,pmax)
Permute(T,d,pmin)
Si pmax > d Alors
Permute(T,f,pmax)
Fsi
d := d+1; f := f-1
Fait
FIN
Tri par Sélection : variante 1

Tri Min Max


Version récursive
Tri_Min_Max(var T : tab; d,f : entier)
VAR i, j, pmin, temp : entier

Début
Si d < f Alors
min_max(T,d,f,pmin,pmax)
Permute(T,d,pmin)
Si pmax > d Alors
Permute(T,f,pmax)
Fsi
Tri_Min_Max(T,d+1,f-1)
Fsi
FIN
TRI PAR INSERTION
Algorithmes élémentaires
Tri par insertion

Lorsqu’on est enfant, il y a un autre algorithme de tri qu’on apprend (ou


découvre) assez vite.
C’est celui que les joueurs de cartes utilisent pour organiser leurs mains.
Le joueur pioche la carte qui est en haut du tas et la place (l’insère) à la bonne
position dans la main.
Cet algorithme se nomme le « tri par insertion ».

19
Tri par insertion
Tri par insertion


Tri par insertion

Auxiliaire

partie triée i partie non triée


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

On insère dans la partie triée en décalant les


éléments vers la droite
Tri par insertion

Tri_insertion(var T : tab; N : entier)


VAR i, j, temp : entier

Début
Pour i de 2 à N faire
temp := T[i]
j := i-1
Tant que j ≥ 1 et T[j] > temp faire
T[j+1] := T[j]
j := j-1
Fait
T[j+1] := temp
Fpour
Fin
TRI À BULLES
Algorithmes élémentaires
Tri à Bulles

Le Tri à bulle est certainement celui qu’on apprend à programmer en premier,


avant même le Tri par sélection et le Tri par insertion.
Pour effectuer un Tri à bulle, il faut parcourir la liste en permutant les
éléments contigus qui ne sont pas dans le bon ordre.
Quand c’est fini, l’élément le plus grand se retrouve donc en queue de liste.
Cet élément est arrivé à sa bonne position, mais le reste de la liste est encore
potentiellement en désordre.
On recommence autant de fois qu’il y a d’éléments dans la liste, ce qui fait
donc à chaque fois remonter le plus grand élément restant.

25
Tri à Bulles

On parcourt le tableau T à trier,

Dès que deux éléments consécutifs T[i] et T[i+1]


(T[i-1] et T[i]) ne sont pas bien placés,
c’est-`a-dire que T[i] > T[i+1], alors on les échange,

On répète le même processus jusqu'à placement


des N éléments
Tri à Bulles
Tri à Bulles


Tri à Bulles


Tri à Bulles

Tri_Bulle_1(var T : tab; N : entier)


VAR i, j : entier

Début
pour i de N à 2 pas(-1) faire
pour j de 1 à i-1 faire
si T[j] > T[j+1] Alors
Permuter(T[j],T[j+1])
Fsi
Fpour
Fpour
Fin
Tri à Bulles

Tri_Bulle_1(var T : tab; N : entier)


VAR i, j : entier

Début
pour i de 1 à N-1 faire
pour j de N à i+1 pas(-1) faire
si T[j-1] > T[j] Alors
Permuter(T[j],T[j-1])
Fsi
fpour
fpour
Fin
Tri à Bulles : 1er amélioration

On parcourt le tableau T à trier,

Dès que deux éléments consécutifs T[i] et T[i+1] (T[i-1] et


T[i]) ne sont pas bien placés,
c’est-`a-dire que T[i] > T[i+1], alors on les échange,

On répète le même processus jusqu'à placement des N


éléments,
Si aucun échange n’a été effectué,
 c’est que le tableau est trié.

 utiliser une variable booléenne (drapeau / flag)


Tri à Bulles : 1er amélioration

Tri_Bulle_2(var T : tab; N : entier)


VAR i, j: entier; estTrie : Booléen
Début
i := N
Répéter
estTrie := VRAI
pour j de 1 à i-1 faire
si T[j] > T[j+1] Alors
Permuter (T[j],T[j+1])
estTrie := FAUX
Fsi
Fpour
i := i + 1
jusqu’à estTrie
Fin
Tri à Bulles : 2èmm amélioration

Shaker Sort
Le tri Shaker, également appelé tri Cocktail ou tri à bulles
bidirectionnel est une variante du tri à bulles.
Son principe est identique à celui du tri à bulles, sauf qu'il
change de direction à chaque passe.

C'est une légère amélioration car il


permet non seulement aux plus grands
éléments de migrer vers la fin de la
série mais également aux plus petits
éléments de migrer vers le début.
Tri à Bulles : 2èmm amélioration

3 5 2 1 4
Shaker Sort

3 5 2 1 4

3 5 2 1 4 3 2 5 1 4

3 2 5 1 4 3 2 1 5 4

3 2 1 5 4 3 2 1 4 5

3 2 1 4 5

3 2 1 4 5


Tri à Bulles : 2èmm amélioration

3 5 2 1 4
Shaker Sort

3 2 1 4 5

3 1 2 4 5 3 1 2 4 5

3 1 2 4 5 1 3 2 4 5

1 3 2 4 5

1 3 2 4 5 1 2 3 4 5

1 2 3 4 5

1 2 3 4 5


1 2 3 4 5
Tri à Bulles : 1er amélioration

tri_shaker(var T : tab; n : entier) Shaker Sort


Var i,j,d,f : entier; estTrie : Booléen
Début
d := 1; f := n
Répéter
estTrie := VRAI
pour i de d à f-1 pas(1) faire
Si (T[i] > T[i+1]) alors
Permute(T[i], T[i+1]); estTrie := FAUX
Fsi
Fpour
f := f - 1
Pour j de f à d+1 pas(-1) faire
Si (T[j] < T[j-1]) alors
Permute(T[j], T[j-1]); estTrie := FAUX
Fsi
Fpour
d := d + 1
jusqu’à (estTrie) ou (f <= d)
FIN
Tri par Dénombrement
Algorithmes élémentaires
Tri par Dénombrement

Le tri par dénombrement (counting sort) est l’un des algorithmes de tri le plus
rapide, et pourtant il est loin d'être compliqué, même s'il a quelques
restrictions et défauts.
Le tri s'exécute en un temps linéaire, mais uniquement sur des nombres
entiers.
La particularité du tri est qu'il est la base d'autres algorithmes de tri en temps
linéaires, permettant de s'adapter aux besoins en temps et en mémoire.
Tri par Dénombrement

Le principe est simple, on parcourt le tableau et on compte le


nombre de fois que chaque élément apparaît.

Une fois qu’on a le tableau de dénombrement D,


avec D[i] le nombre de fois où i apparaît dans le
tableau, on peut le parcourir dans le sens :
• croissant (pour un tri croissant)
• décroissant (pour un tri décroissant)
et placer dans le tableau trié D[i] fois l’élément i,
Avec i allant de l’élément minimum du tableau
jusqu’à l’élément maximum
Tri par Dénombrement

Un ensemble de N entiers appartenant à [0..P]


1 2 3 4 5 6 7 8

T 2 3 5 4 2 1 2 3

Utiliser un tableau de dénombrement


0 1 2 3 4 5

D 0 1 3 2 1 1

Construire le tableau trié


1 2 3 4 5 6 7 8

T 1 2 2 2 3 3 4 5
Tri par Dénombrement

Tri_dénombrement(Var T:Tab, N:entier, P:entier)


VAR i,j,k : entier; D : TabD

Début
Tab_dénombrement(T,N,D,P)
k := 1
Pour i de 0 à P faire
Si D[i] <> 0 Alors
pour j de 1 à D[i] faire
T[k]:= i
k := k + 1
Fpour
Fsi
Fpour
Fin

N.B. : TabD : Tableau [0 .. Max] de Entier


Tri par Dénombrement

Tab_dénombrement(S:Tab, N:entier, Var D:TabD, P:entier)


VAR i : entier

Début
Pour i de 0 à P faire
D[i] := 0
Fpour

Pour i de 1 à N faire
D[S[i]] := D[S[i]] + 1
Fpour
Fin

N.B. : TabD : Tableau [0 .. Max] de Entier


Tri GNOME
Algorithmes élémentaires
Tri GNOME

Cet algorithme est appelé "Gnome Sort" !!!


parce qu'il parait que c'est la méthode qu'utilisent les nains de jardin (Gnome)
hollandais pour trier une rangée de pots de fleurs,
L'algorithme est similaire au tri par insertion, sauf que, au lieu d’insérer
directement l'élément à sa bonne place, l'algorithme effectue une série de
permutations, comme dans un tri bulle.

45
Tri GNOME

Principe
on compare deux éléments consécutifs :
• s’ils sont dans l’ordre on se déplace d’un pas vers la
fin du tableau (ou on s’arrête si la fin est atteinte),
• sinon, on les permute et on se déplace d’un pas vers
le début du tableau,
on commence par le début du tableau
Tri GNOME

3 5 2 1 4

3 5 2 1 4

3 5 2 1 4 3 2 5 1 4

3 2 5 1 4 2 3 5 1 4

2 3 5 1 4

2 3 5 1 4 2 3 1 5 4

2 3 1 5 4 2 1 3 5 4

2 1 3 5 4 1 2 3 5 4

1 2 3 5 4
Tri GNOME

3 5 2 1 4

1 2 3 5 4

1 2 3 5 4

1 2 3 5 4 1 2 3 4 5

1 2 3 4 5

1 2 3 4 5
Tri GNOME

Tri_Gnome(S:Tab, N:entier)
VAR i : entier

Début
pos := 2
Tant que pos <= N faire
Si T[pos] >= T[pos-1] alors
pos := pos + 1
Sinon
Permutation(T[pos],T[pos-1])
Si pos > 2 alors
pos := pos - 1
Fsi
Fsi
Ftant que
FiN
Tri Fusion
Algorithmes élémentaires
Tri Fusion

Dans la grande famille des tris reposant sur le principe « diviser pour régner
», on trouve le Tri Fusion.
À mon sens, le Tri Fusion est au Tri rapide ce que le Tri par insertion est au Tri
par sélection.
Dans cette famille de tri, on travaille toujours en trois phases :
1. D’abord on divise.
2. Ensuite on règne.
3. Et pour finir, on réconcilie (fusionne).

Alors que, pour le Tri rapide , tout se fait à la construction de l’arbre, pour le
Tri Fusion , la partie intéressante se situe lors de la phase de réconciliation.

51
Tri Fusion

Pour réaliser un Tri Fusion, on commence par diviser la liste à


trier en deux sous-listes de même taille.
On réitère récursivement cette opération jusqu’à n’avoir que
des listes d’un seul élément.
Cela produit donc un arbre à peu près équilibré.
On remonte ensuite dans l’arbre en fusionnant les sous-listes à
chaque étape.
Pour cela, on prend le plus petit élément qui se présente en
tête des deux sous-listes à fusionner et on recommence tant
qu’il reste des éléments.
Quand on revient à la « racine » de l’arbre, la liste est triée.
Tri Fusion

Principe
• Partager le tableau en 2 parties
• Trier récursivement chaque partie
• Fusionner les 2 parties
Tri Fusion
Tri Fusion

Tri_Fusion(T:Tab, d,f:entier, Var R:Tab)


VAR m : entier, R1, R2 :Tab

Début
Si d ≤ f alors
Si d = f alors
R[d] := T[d]
Sinon
m := (d + f) div 2
Tri_Fusion(T,d,m,R1)
Tri_Fusion(T,m+1,f,R2)
Fusion(R1,d,m,R2,m+1,f,R)
Fsi
Fsi
FiN
Tri Fusion

Fusion (A:Tab, dA,fA: Entier; B:Tab, dB,fB: Entier;


Var C : Tab; dC,fC : Entier)

Début
Tant que (dA <= fA) ET (dB <= fB) Faire
Si A[dA] <= B[dB] alors
C[dC]:= A[dA]
dA := dA + 1
Sinon
C[dC] := B[dB]
dB := dB + 1
Fin Si
dC := dC + 1
Ftantq
...
Tri Fusion

Fusion (A:Tab, dA,fA: Entier; B:Tab, dB,fB: Entier;


Var C : Tab; dC,fC : Entier)

Début

...
Tant que (dA <= fA) Faire
C[dC] := A[dA]
dA := dA + 1
dC := dC + 1
Ftantq

Tant que (dB <= fB) Faire


C[dC] := B[dB]
dB := dB + 1
dC := dC + 1
Ftantq
Fin
Tri Rapide
Algorithmes élémentaires
Tri Rapide

C’est l’un des algorithmes les plus utilisés et certainement celui qui présente
le plus de variantes. Le Tri rapide, aussi appelé Quick Sort , fait partie de la
famille d’algorithme dont le fonctionnement repose sur le principe «diviser
pour régner».
Pour réaliser un Tri rapide, on doit choisir un élément dans la liste, qu’on
appelle pivot.
On divise ensuite la liste en deux sous-listes. La première, à gauche, contient
les éléments inférieurs au pivot. La seconde, à droite, contient les éléments
supérieurs au pivot.

les éléments ≤ à x pivot les éléments > à x


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

59
Tri Rapide

C’est l’un des algorithmes les plus utilisés et certainement celui qui présente
le plus de variantes. Le Tri rapide, aussi appelé Quick Sort , fait partie de la
famille d’algorithme dont le fonctionnement repose sur le principe «diviser
pour régner».
Pour réaliser un Tri rapide, on doit choisir un élément dans la liste, qu’on
appelle pivot.
On divise ensuite la liste en deux sous-listes. La première, à gauche, contient
les éléments inférieurs au pivot. La seconde, à droite, contient les éléments
supérieurs au pivot.
On reproduit alors récursivement ce choix du pivot et la division sur les listes
de gauche et de droite précédemment construites jusqu’à n’avoir que des
sous-listes de zéro ou un élément.
Pour finir, il suffit de rassembler les éléments de toutes les sous-listes dans
l’ordre gauche-droite.
60
Tri Rapide

Principe
• Diviser le tableau en deux parties séparées par un
élément (appelé pivot) de telle manière que :

les éléments ≤ à x pivot les éléments > à x


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

• Appliquer la récursivité sur les deux parties ainsi


crées
Tri Rapide
Tri Rapide

La grosse difficulté
du Tri rapide réside
dans le choix du bon
pivot, le risque
étant de
déséquilibrer les
sous-listes qu’on va
construire.
Quand on n’a pas de
meilleure idée et
faute de mieux, on
peut prendre le
premier élément,
Tri Rapide

Et quand on n’a aucune information


sur les données, on peut également
choisir le pivot de manière aléatoire.
Tri Rapide

Tri_Rapide(T : Tab, d,f : entier)


VAR m : entier

Début
Si d < f Alors
m := Partition(T, d, f)
Tri_Rapide(T, d, m-1)
Tri_Rapide(T, m+1, f)
fsi
FiN
Tri Rapide

Partition(T : Tab, d,f : entier) : entier


VAR i, j : entier
piv : entier

Début
piv := T[d]
i := d
j := f + 1
Répéter
Répéter i := i + 1 jqa (T[i] ≥ piv ou i ≥ j)
Répéter j := j – 1 jqa (T[j] ≤ piv ou j < i)
si i < j Alors
Permutation(T,i,j)
Fsi
jusqu’a j ≤ i
Permutation(T,d,j)
Partition := j
FiN
LA CLASSIFICATION
DES ALGORITHMES DE TRI

Algorithmes élémentaires
La classification des algorithmes de tri

La classification des algorithmes de tri est très


importante, car elle permet de choisir l’algorithme
le plus adapté au problème traité, tout en tenant
compte des contraintes imposées par celui-ci.
Les principales caractéristiques qui permettent de
différencier les algorithmes de tri, outre leur
principe de fonctionnement, sont la complexité
temporelle, la complexité spatiale et le caractère
stable.

68
Le problème du tri

Tri en place

• Un tri est dit en place s'il n'utilise qu'un nombre très


limité de variables et qu’il modifie directement la
structure qu’il est en train de trier.
• Ceci nécessite l’utilisation d'une structure de donnée
adaptée (un tableau par exemple).
• Ce caractère peut être très important si on ne dispose
pas de beaucoup de mémoire.
• Toutefois, on ne déplace pas, en général, les données
elles-mêmes, mais on modifie seulement des
références (ou pointeurs) vers ces dernières.

69
Le problème du tri

Tri stable

• Un tri est dit stable s'il préserve l’ordonnancement initial


des éléments que l'ordre considère comme égaux.
• Pour définir cette notion, il est nécessaire que la
collection à trier soit ordonnancée d'une certaine
manière (ce qui est souvent le cas pour beaucoup de
structures de données, par exemple pour les listes ou les
tableaux).
• Les algorithmes de tri instables peuvent être retravaillés
spécifiquement afin de les rendre stables, cependant
cela peut être aux dépens de la rapidité et/ou peut
nécessiter un espace mémoire supplémentaire.

70
Le problème du tri

Tri interne & Tri externe

• Un tri interne s'effectue entièrement en mémoire centrale


tandis qu'un tri externe utilise des fichiers sur une mémoire de
masse pour trier des volumes trop importants pour pouvoir
tenir en mémoire centrale.
• Certains types de tris, comme le tri fusion ou les tris par
distribution, s'adaptent facilement à l'utilisation de mémoire
externe.
• D'autres algorithmes, à l'inverse, accèdent aux données de
telle sorte qu'ils ne se prêtent pas à cet usage car cela
nécessiterait d'effectuer constamment des lectures/écritures
entre les mémoires principale et externe.

71
Le problème du tri

Tri parallèle

• Certains algorithmes permettent d'exploiter les capacités


multitâches de la machine.
• Notons également que certains algorithmes, notamment
ceux qui fonctionnent par insertion, peuvent être lancés
sans connaître l'intégralité des données à trier; on peut
alors trier et produire les données à trier en parallèle.

72
principaux algorithmes de tri : Stable

Cas Cas Pire


Stable optimal moyen des cas
Tri par insertion (*) n log(n) n2 n2

Tri à bulles (*) n n2 n2

Tri Cocktail | Shaker (*) n n2 n2

Tri Fusion (*) n log(n) n log(n) n log(n)


Tri pair-impair n n2 n2
version parallèle du tri à bulles

Tri hybride (Timsort) n n log(n) n log(n)


tri fusion & tri par insertion

Tri arborescent n log(n) n log(n) n log(n)


utilise la structure ABR | équivalent au tri rapide (Arbre équilibré)

73
principaux algorithmes de tri : Instable

Cas Cas Pire


Instable optimal moyen des cas
Tri par sélection (*) n2 n2 n2

Tri Rapide (*) n log(n) n log(n) n2


Tri par tas n log(n) n log(n) n log(n)
cherche à obtenir un tas, AB

Tri de Shell n n log2(n) n log2(n)


amélioration du tri par insertion | tri H ou n3/2 (suite d'espacements connue)

Introsort n log(n) n log(n) n log(n)


variante du tri Rapide | profondeur de récursion n log(n)

Smoothsort n n log(n) n log(n)


tri par comparaison | inspiré de tri par tas

Tri à peigne n n log(n) n2

74
Application

Soit un tableau T d’entiers contenant des éléments ordonnés suivis par quelques
éléments dans un ordre quelconque (autrement dit T est partiellement trié).
On suppose que le nombre d'éléments ordonnés est largement supérieur à celui
des éléments non ordonnés.

Si vous avez à trier un tel tableau, quelle méthode de tri choisirez-vous? Justifiez
votre réponse.

75
Application

Tri par insertion

on n’a aucune idée sur les éléments non triés par rapport aux éléments triés (plus
petits / plus grands) donc les éléments peuvent ne pas occuper leurs positions
finales.
Alors qu’avec le tri par sélection ou le tri bulle les éléments de la partie triée sont à
leurs positions définitives et ils ne bougeront plus jamais.

76

Vous aimerez peut-être aussi