Vous êtes sur la page 1sur 14

Algorithmes de tri Mme Z.

TAHAKOURT

Chapitre 2 :

Algorithmes de tri

1. Introduction

Dans ce chapitre on présente quelques algorithmes utiles, qui permettent d'ordonner les
éléments d'un tableau dans un ordre croissant ou décroissant. L'ordre est par défaut
croissant. Nous calculerons la complexité de chaque algorithme.
2. Tri par insertion
2.1 Principe
Le principe de cet algorithme est de commencer par trier les deux premiers éléments puis,
considérer que le tableau est divisé en deux parties de tailles variables ; une dans laquelle
les données sont triées (Au début de l'algorithme composée des deux premiers éléments) et
l'autre contenant les données à trier. On prend un à un les éléments de la partie non triée du
tableau et on l’insère au bon endroit dans la partie triée du tableau en déplaçant tous les
éléments qui le précède. Dès que l'élément à insérer est plus grand qu'un des éléments de la
partie triée du tableau, il n'y a plus de déplacement, et l'élément est inséré dans la case laissé
vacante par les éléments qui ont été déplacés.

2.2 Algorithme de tri par insertion

Procédure TriInsertion (Var T :Tableau [1..100] d’entiers ;n :


entier) ;
Var i, j, x: entier ;
Début
Pour i allant de 2 à n Faire
x  T[i] ;
j  i-1 ;
Tant que j>0 et T[j]>x Faire
T[j+1] T[j] ;
jj-1 ;
FTq
T[j+1]X ;
Fpour
Fin

1
Algorithmes de tri Mme Z. TAHAKOURT

2.3 Exemple
Soit à trier le tableau T suivant : [20, 4, 1, 5, 23, 7, 8, 3]

N° i j x T[1 T[2 T[3 T[4 T[5 T[6 T[7 T[8


iterati ] ] ] ] ] ] ] ]
on
1 Initialisati 20 4 1 5 23 7 8 3
on
2 2 1 4 20 20 1 5 23 7 8 3
3 2 0 4 4 20 1 5 23 7 8 3
4 3 2 1 4 20 20 5 23 7 8 3
5 3 1 1 4 4 20 5 23 7 8 3
6 3 0 1 1 4 20 5 23 7 8 3
7 4 3 5 1 4 20 20 23 7 8 3
8 4 2 5 1 4 5 20 23 7 8 3
9 5 4 23 1 4 5 20 23 7 8 3
10 6 5 7 1 4 5 20 23 23 8 3
11 6 4 7 1 4 5 20 20 23 8 3
12 6 3 7 1 4 5 7 20 23 8 3
13 7 6 8 1 4 5 7 20 23 23 3
14 7 5 8 1 4 5 7 20 20 23 3
15 7 4 8 1 4 5 7 8 20 23 3
16 8 7 3 1 4 5 7 8 20 23 23
17 8 6 3 1 4 5 7 8 20 20 23
18 8 5 3 1 4 5 7 8 8 20 23
19 8 4 3 1 4 5 7 7 8 20 23
20 8 3 3 1 4 5 5 7 8 20 23
21 8 2 1 4 4 5 7 8 20 23
22 8 1 3 1 3 4 5 7 8 20 23

2
Algorithmes de tri Mme Z. TAHAKOURT

2.4 Calcul de la complexité de l’algorithme de tri par insertion


Le pire des cas pour cet algorithme est le cas où le tableau, en entrée, est initialement trié dans
un ordre décroissant. Dans ce cas, le coût C(n) de cet algorithme est calculé comme suit:

Nombre Nombre
Instruction Cout
d’opérations d’exécution
i← 2 1 1 1
𝑖 ≤n 1 N n
x  T[i] ; 1 n-1 n-1
j← i-1 2 n-1 2(n-1)
𝑛

j>0 et T[j]>x 3 ∑𝑗 3 ∑𝑛𝑗=2 𝑗


𝑗=2
𝑛−1

A[j+1] ← A[j] 2 ∑𝑗 2 ∑𝑛−1


𝑗=1 𝑗
𝑗=1
𝑛−1

𝑗 ←j-1 2 ∑𝑗 2 ∑𝑛−1
𝑗=1 𝑗
𝑗=1
A[j+1] ← X 2 n-1 2(n-1)
i← i+1 2 n-1 2(n-1)

n n−1

C(n) = 1 + n + 7(n − 1) + 3 ∑ j + 4 ∑ j
2 1

C(n) = 8n − 6 + 3(∑n1 j − 1) + 4(∑n1 j − n) ; posons z = ∑n1 j

C(n) = 8n − 6 + 3(z − 1) + 4(z − n) = 4n − 9 + 7z

z est la somme des n premiers termes d’une suite arithmétique dont le premier
n(n+1)
terme est 1 et de raison r=1, donc z = 2

n2 + n
C(n) = 4n − 9 + 7
2

𝑛2 24n
C(n) = 4 +7 −9
2 2

Ainsi, La complexité de l’algorithme du tri par insertion est en O(n2).

3
Algorithmes de tri Mme Z. TAHAKOURT

3. Tri à Bulle
3.1 Principe

Le principe est de parcourir la liste (a1, a2, ..., an) en permutant toute paire d'éléments
consécutifs (ai-1, ai) non ordonnés. Ainsi après le premier parcours, l'élément maximum se
retrouve à la fin du tableau.
Le nom de tri à bulle vient donc de ce qu'à la fin de chaque itération interne, les plus grands
nombres de chaque sous-suite se déplacent vers la droite successivement comme des bulles de
la gauche vers la droite.
3.2 Algorithme de tri à Bulles

Procédure TriBulle (Var T: Tableau [1..100] d’entiers ;n :


entier) ;
Var i, j, tmp: entier ;
Début
Pour i allant de n à 1 Faire
pour j allant de 2 à i faire
si T[ j-1 ] > T[ j ] alors
tmp  T[ j-1 ] ;
T[ j-1 ]  T[ j ] ;
T[ j ]  tmp ;
Fsi
fpour
fpour
Fin
3.3 Exemple

Soit à trier le tableau T suivant : [20, 4, 1, 5, 23, 7, 8, 3]

i j T[1] T[2] T[3] T[4] T[5] T[6] T[7] T[8]


Initialisation 20 4 1 5 23 7 8 3
8 2 4 20 1 5 23 7 8 3
8 3 4 1 20 5 23 7 8 3
8 4 4 1 5 20 23 7 8 3
8 5 4 1 5 20 23 7 8 3
8 6 4 1 5 20 7 23 8 3
8 7 4 1 5 20 7 8 23 3
8 8 4 1 5 20 7 8 3 23 23
7 2 1 4 5 20 7 8 3 23
7 3 1 4 5 20 7 8 3 23
7 4 1 4 5 20 7 8 3 23
7 5 1 4 5 7 20 8 3 23
7 6 1 4 5 7 8 20 3 23
7 7 1 4 5 7 8 3 20 23
4
Algorithmes de tri Mme Z. TAHAKOURT

20
6 2 1 4 5 7 8 3 20 23
6 3 1 4 5 7 8 3 20 23
6 4 1 4 5 7 8 3 20 23
6 5 1 4 5 7 8 3 20 23
6 6 1 4 5 7 3 8 20 23 8
5 2 1 4 5 7 3 8 20 23
5 3 1 4 5 7 3 8 20 23
5 4 1 3 5 7 3 8 20 23
5 5 1 4 5 3 7 8 20 23 7
4 2 1 4 5 3 7 8 20 23
4 3 1 4 5 3 7 8 20 23
5
4 4 1 4 3 5 7 8 20 23
3 2 1 4 3 5 7 8 20 23
4
3 3 1 3 4 5 7 8 20 23
2 2 1 3 4 5 7 8 20 23
3
1 2 1 3 4 5 7 8 20 23
1

3.4 Calcul de la complexité de l’algorithme de tri à bulles

Le pire des cas pour cet algorithme est le cas où le tableau, en entrée, est initialement trié dans
un ordre décroissant. Dans ce cas, le coût C(n) de cet algorithme est calculé comme suit:

Nombre Nombre
Instruction Cout
d’opérations d’exécution
i← 𝑛 1 1 1
𝑖 ≥1 1 n n+1
i← i-1 2 1 n
j← 2 1 n n
𝑛 𝑛

𝑗≤𝑖 1 ∑𝑖 ∑𝑖
𝑖=1 𝑖=1
𝑛 𝑛

j← j+1 2 ∑𝑖 2 ∗ ∑𝑖
𝑖=1 𝑖=1
𝑛−1 𝑛−1
Tab[j-1] > Tab[j] 1 ∑𝑖 ∑𝑖
𝑖=1 𝑖=1
𝑛−1 𝑛−1
Permutation 3 ∑𝑖 3∗∑𝑖
𝑖=1 𝑖=1

n n−1

C(n) = 3 ∗ n + 2 + 3 ∗ ∑ i + 4 ∗ ∑ 𝑖
i=1 i=1

5
Algorithmes de tri Mme Z. TAHAKOURT

n n

C(n) = 3 ∗ n + 2 + 3 ∗ ∑ i + 4 ∗ (∑ 𝑖 − 𝑛)
i=1 i=1

n n

C(n) = 3 ∗ n + 2 + 3 ∗ ∑ i + 4 ∗ ∑ 𝑖 − 4 ∗ 𝑛
i=1 i=1

C(n) = −n + 2 + 7 ∗ ∑ni=1 i ; ∑ni=1 i =n(n-1)/2 = ½(n2-n)

7 8
C(n) = 2 n2 − 2 n + 2

Ainsi, La complexité de l’algorithme du tri par insertion est en O(n2).

4. Tri par Sélection


4.1 Principe
L'idée est simple : rechercher le plus grand élément (ou le plus petit), le placer en fin de tableau
(ou en début), recommencer avec le second plus grand (ou le second plus petit), le placer en
avant-dernière position (ou en seconde position) et ainsi de suite jusqu'à avoir parcouru la
totalité du tableau.

4.2 Algorithme de tri par Sélection

Procédure TriSélection (Var Tab: Tableau [1..100] d’entiers ;n :


entier) ;
Var i, j, m, tmp: entier;
Début
Pour i allant de 1 à n-1 Faire
m  i ;
pour j allant de i+1 à n faire
si T[j] < T[m] alors
m j ;
tmp  T[ m ] ;
T[ m ]  T[ i ] ;
T[ i ]  tmp ;
m i ;

Fsi
fpour
fpour
Fin
4.3 Exemple
Dérouler l’algorithme de tri par sélection sur le tableau T suivant : [20, 4, 1, 5, 23, 7, 8, 3].

6
Algorithmes de tri Mme Z. TAHAKOURT

4.4 Calcul de la complexité de l’algorithme de tri par sélection


Dans tous les cas, pour trier n éléments, le tri par sélection effectue n(n-1)/2 comparaisons. Sa
complexité est donc O(n2).

5. Complexité des algorithmes du type diviser pour régner


5.1Le paradigme « Diviser pour régner »

Le principe algorithmique dit diviser pour régner consiste à :

1. Diviser l'instance d'un problème en sous-instances,


2. Traiter indépendamment ces sous-instances,
3. Combiner les différents résultats obtenus pour construire une solution au problème
initial.

Les algorithmes qui s'appuient sur ce principe sont souvent récursifs et opèrent sur des instances
de plus en plus petites jusqu'à ce que la taille de l'instance à traiter rende la résolution du
problème simple voire triviale. Ce principe algorithmique permet d’obtenir de meilleures
fonctions de complexité qu'avec une approche naïve ou globale, d'où sa popularité.

Complexité avec Complexité avec l'algorithme


Exemple d’algorithme
l’algorithme naïf diviser pour régner
Recherche dans un tableau O(n) (Voir chapitre1 p.7 ) O(log n) avec l’algorithme
trié de taille n dichotomique)
Tri d'un tableau de n O(n²) (voir p.1 tri insertion, tri O(n log n) avec le tri fusion, tri
éléments sélection) rapide

multiplication de matrices O(n3) O(n2)

7
Algorithmes de tri Mme Z. TAHAKOURT

5.2Principe du paradigme « Diviser pour régner »

Les algorithmes qui s'appuient sur ce principe sont souvent récursifs et opèrent sur des
instances de plus en plus petites jusqu'à ce que la taille de l'instance à traiter rende la résolution
du problème simple voire triviale.
La suite des instructions qui définissent un algorithme récursif, d’entrée x de taille n, sont
constituées d'un certain nombre d'appels récursifs, que l'on notera a, sur des entrées yi dont la
taille est une fraction n/b de la taille n de x. Les opérations réalisées par l'algorithme en dehors
de ces appels récursifs, prétraitement (incluant le partitionnement de x) et post-traitement
(incluant la reconstitution du résultat), ont un coût noté f(n). Pour résumer, on a les variables
suivantes :

1. n est la taille de l'instance du problème à traiter ;


2. a est le nombre d'appels récursifs ;
3. n/b est la taille (constante) des a sous-instances ;
4. f(n) est le coût des instructions hors appels récursifs, c.-à-d. le cout de la division du
problème initial et de la construction de la solution finale.

Dans le cas où n=1, le coût de traitement est supposé constant, donc en O (1). Si l'on note T(n)
la complexité de cet algorithme, on obtient directement la formule récurrente
𝑂(1) 𝑠𝑖 𝑛 = 1
{ 𝑛
𝑇(𝑛) = 𝑎 𝑇 (𝑏 ) + 𝑓(𝑛) 𝑠𝑖𝑛𝑜𝑛

Le théorème maître permet de résoudre ce type d’équations.

5.2.1 Théorème Maître ou Master Theorem :


𝑛
On considère l’équation 𝑇(𝑛) = 𝑎 𝑇 (𝑏 ) + 𝑂(𝑛𝑑 ) , posons 𝛼 = 𝑙𝑜𝑔𝑏 𝑎
On a les trois cas suivants :
1. si 𝛼 > 𝑑 alors 𝑇(𝑛) = O(𝑛𝛼 )
2. si 𝛼 = 𝑑 alors 𝑇(𝑛) = O(𝑛𝛼 log 𝑛)
3. si 𝛼 < 𝑑 alors 𝑇(𝑛) = O(𝑛𝑑 )

Remarque très importante


En pratique, seuls les cas 1 et 2 peuvent mener à des solutions algorithmiques intéressantes.
Dans le cas 3, tout le coût est concentré dans la phase “recombiner”, ce qui signifie souvent qu’il y a des
solutions plus efficaces

8
Algorithmes de tri Mme Z. TAHAKOURT

6. Tri par Fusion


6.1Principe

L’algorithme de tri par fusion est construit suivant le paradigme « diviser pour régner ». Pour
trier un tableau de n entier, cet algorithme commence par le diviser en deux sous-tableaux de
taille n/2. Il trie récursivement les deux sous-tableaux, puis les fusionne pour produire le tableau
résultat trié.
La recursion termine quand le sous-tableau à trier est de longueur 1 car un tel tableau est
toujours trié.

6.2Algorithme TriFusion
Procédure TriFusion(var T:Tableau[1..n]d’entiers,début,fin:entier);
Var milieu : entier
Début
Si (début < fin) Alors
milieu ←(début + fin)/2 ;
TriFusion(A, début, milieu) ;
TriFusion(A, milieu+1, fin) ;
Fusionner(A,debut,milieu,fin) ;
FSi ;
Fin ;

Procédure Fusionner(var A[n]: Tableau, début, milieu, fin: entier) ;


Variables i, i1, i2 : entier ; tmp: Tableau [1..n] d’entiers ;
Début
i ←1 ; i1 ←début ; i2 ←milieu + 1 ;
Tq (i1 <= milieu) et (i2 <= fin) Faire
Si A[i1] < A[i2] Alors
tmp[i] ←A[i1] ;
i1 ← i1 +1 ;
Sinon
tmp[i] ←A[i2] ;
i2 ←i2 + 1;
FSi ;
i ←i + 1 ;
FTq ;
Tq ( i1 <= milieu) Faire
tmp[i] ← A[i1] ; i ←i + 1 ; i1 ←i1 + 1 ;
FTq ;
Tq (i2 <= fin) Faire
Tmp[i] ← A[i2] ; i ←i + 1 ; i2 ←i2 + 1 ;
FTq ;
A ← Tmp ;
Fin ;

9
Algorithmes de tri Mme Z. TAHAKOURT

6.3Complexité

Pour déterminer la formule de récurrence qui nous donnera la complexité de l’algorithme


TriFusion, nous étudions les trois phases de cet algorithme « diviser pour régner » :
 Diviser : cette étape se réduit au calcul du milieu de l’intervalle [debut..fin], il est de
O(1)
 Régner : l’algorithme résout récursivement deux sous-problèmes de tailles respectives
n/2
 Combiner : la complexité de cette étape est celle de l’algorithme de fusion qui est de
O(n) pour la construction d’un tableau solution de taille n.

La complexité du tri par fusion est donnée par le Master Theorem par la relation de récurrence :
𝒏
𝑻(𝒏) = 𝒂 𝑻 ( ) + 𝒇(𝒏)
𝒃
f(n) étant la complexité des instructions hors appels récursifs : 𝒇(𝒏) = 𝑶(𝟏) + 𝑶(𝒏) = 𝑶(𝒏)
On a donc 𝑑 = 1 et 𝛼 = 2 , 𝛽 = 2 donc 𝑙𝑜𝑔𝑏 𝑎 = 1
Nous nous trouvons donc, dans le deuxième cas du théorème, 𝑻(𝒏) = 𝑶(𝒏𝒍𝒐𝒈𝒏)

Donc pour des valeurs de n suffisamment grandes, le tri par fusion avec son temps d’exécution
en O(𝑛 log 𝑛) est nettement plus efficace que le tri par insertion dont le temps d’exécution est
en O(𝑛).

10
Algorithmes de tri Mme Z. TAHAKOURT

7. Tri rapide
7.1Principe

Le tri rapide, ou quicksort, fait partie des tris qui utilisent les comparaisons. Son principe
suit l'approche "diviser pour régner" : on sélectionne un élément de l'ensemble (le pivot)
avant de placer d'un côté les éléments inférieurs ou égaux au pivot, et de l'autre ceux qui lui
sont supérieurs. On parle de partitionnement. On applique à nouveau le même procédé sur
les deux sous-ensembles, et ainsi de suite. Le premier élément de la partie à diviser est
généralement choisi comme élément pivot.

7.2Algorithme TriRapide
Procédure TriRapide (var A: Tableau[1..n] d’entiers, d,
f:entier) ;
Variables mur, i, pivot : entier ;
Début
pivot ← A[d];
mur ← d ;
(* mur marque la séparation entre les éléments plus petits
et ceux plus grands que pivot*)
Pour i ← d+1 à f Faire
si (A[i] <= pivot) alors
Permuter (A[i], A[mur]);
mur ← mur + 1 ;
fsi ;
FPour
(* On poursuit par récursivité *)
Si (d < mur-1) alors
TriRapide (A, d, mur-1) ;
Si(mur+1<f) alors
TriRapide (A, mur, f) ;
Fin

11
Algorithmes de tri Mme Z. TAHAKOURT

7.3Exemple

Soit à trier le tableau T suivant : [20, 4, 1, 5, 23, 7, 8, 3]


On appelle la procédure TriRapide (T, 1, 8)

Pivot mur i T[1] T[2] T[3] T[4] T[5] T[6] T[7] T[8]
initialisation 20 4 1 5 23 7 8 3
20 1 2 4 20 1 5 23 7 8 3
20 2 3 4 1 20 5 23 7 8 3
20 3 4 4 1 5 20 23 7 8 3
20 4 5 4 1 5 20 23 7 8 3
20 4 6 4 1 5 7 23 20 8 3
20 5 7 4 1 5 7 8 20 23 3
20 6 8 4 1 5 7 8 3 23 20
20 7 9 4 1 5 7 8 3 23 20

Les deux parties (jaune et bleue) du tableau T seront traitées récursivement et ainsi de suite.
Essayer de terminer le déroulement de cet algorithme sur cet exemple.

7.4Complexité de l’algorithme TriRapide

Afin de calculer la complexité de cet algorithme, considérons le pire, moyen et meilleur cas.

7.4.1 Complexité de l’algorithme TriRapide dans le pire cas

Le pire des cas pour cet algorithme est le cas où le tableau, en entrée, est initialement trié dans
un ordre décroissant. Dans ce cas, le pivot sera toujours la plus grande valeur du tableau qui
trouvera, à chaque fois, sa place au niveau de la dernière case du tableau. Ainsi, à chaque appel
récursif nous aurons à trier un seul sous-tableau de taille (n-1) et non pas deux. Par conséquent,
le nombre de comparaisons T(n) effectuées avec l'algorithme du tri rapide sera calculé comme
suit:
𝑇(𝑛) = (𝑛 − 1) + 𝑇(𝑛 − 1)
𝑇(𝑛) = (𝑛 − 1) + ((𝑛 − 2) + 𝑇(𝑛 − 2))
𝑇(𝑛) = (𝑛 − 1) + ((𝑛 − 2) + ((𝑛 − 3) + 𝑇(𝑛 − 3))
.
.
.
𝑇(𝑛) = (𝑛 − 1) + (𝑛 − 2) + (𝑛 − 3) + ⋯ + 𝑇(1)
𝑇(𝑛) = (𝑛 − 1) + (𝑛 − 2) + (𝑛 − 3) + ⋯ + 1
n−1

T(n) = ∑ i
1
𝑛(𝑛−1) 1
𝑇(𝑛) = = 2 (𝑛2 − 𝑛)
2

La complexité de l’algorithme du tri rapide en nombre de comparaisons est donc en O(n2).


12
Algorithmes de tri Mme Z. TAHAKOURT

7.4.2 Complexité de l’algorithme TriRapide dans le moyen cas

Si à chaque appel récursif, nous obtenons deux sous-tableaux ayant autant de valeurs inférieures
au pivot que de valeurs supérieures au pivot, alors il est possible d'appliquer le Master Théorème
pour calculer la complexité de l'algorithme du Tri rapide.

𝑛
Dans ce cas: 𝑇(𝑛) = 2 𝑇 ( 2) + O(𝑛)  𝑇(𝑛) = O(𝑛 log 𝑛)

7.4.3 Complexité de l’algorithme TriRapide dans le meilleur cas

Exercice : calculer cette complexité.

13
Algorithmes de tri Mme Z. TAHAKOURT

1. Recherche dichotomique
1.1Principe

Si T est un tableau trié de taille n, on s’intéresse à l’algorithme qui recherche si une valeur x
existe dans T au moyen d’une dichotomie. Pour l’algorithme récursif, on spécifie un indice de
début d et de fin f, et on recherche si x est dans T entre les positions d et f. L’appel initial se fait
avec d = 1 et f = n.

1.2Algorithme RechercheDich
Procédure RechercheDich (var A : Tableau [1..n] d’entiers ; x,
d, f : Eentier) ;
Variables : entier
Début
Si f < d Alors
return Faux
Sinon
m = [(d+f)/2]
Si T[m] = x Alors
return Vrai
Sinon
Si T[m] < x Alors
RechercheDich (T,x,m + 1,f)
Sinon
RechercheDich (T,x,d,m − 1)
FSi
FSi
FSi
Fin
1.3Complexité de l’algorithme RechercheDich

On identifie les paramètres : a = 1 car on appelle soit à gauche, soit à droite (ou on a fini, mais
on se place dans le pire des cas), b = 2 car les sous-problèmes sont de taille n/2 et d = 0 car on
se contente de renvoyer la solution, donc en temps constant. La complexité de la dichotomie
est donc O(log n).

14

Vous aimerez peut-être aussi