Vous êtes sur la page 1sur 18

Méthodes de tri

Les méthodes de tri


Les méthodes de tri permettent le réarrangement de données.

Par exemple, le fichier :


Philippe 21
Jean 33
Lineda 27
peut être trié par nom :
Jean 33
Lineda 27
Philippe 21
ou trié par âge :
Philippe 21
Lineda 27
Jean 33
Benoît Charroux - Tris - Septembre 98 - 2
Les méthodes de tri

Pour pouvoir comparer les méthodes de tris, on les appliquent à des tableaux d’entiers.

Tableau non trié : 20 6 1 3 1 7


Indices : 0 1 2 3 4 5

Tableau trié : 1 1 3 6 7 20
Indices : 0 1 2 3 4 5

&RQVWDQWH N 
3URJUDPPHGHWUL 3URFpGXUH tri( t: tab en entrée sortie )
$OJRULWKPH $OJRULWKPH

'pEXW 'pEXW

7\SH tab = WDEOHDX[ N ]: HQWLHU ...


9DULDEOH t: tab )LQ

tri( t )
)LQ

Benoît Charroux - Tris - Septembre 98 - 3

Tri par sélection


Méthode :
on cherche l’élément de plus petite valeur pour l’échanger avec l’élément en
première position ;
puis on cherche l’élément ayant la deuxième plus petite valeur pour l’échanger
avec l’élément en deuxième position ;
et ainsi de suite.
20 6 1 3 1 7
1 6 20 3 1 7
1 1 20 3 6 7
1 1 3 20 6 7
1 1 3 6 20 7
1 1 3 6 7 20

Il faut :
• 1 boucle pour parcourir le tableau et sélectionner tous les éléments ;
• 1 boucle pour rechercher le minimum parmi les éléments non triés.

Benoît Charroux - Tris - Septembre 98 - 4


Algorithme du tri par sélection
3URFpGXUH triSélection( t: tab en entrée sortie )
$OJRULWKPH

'pEXW

9DULDEOHV i, j, min, tmp : HQWLHU


3RXU i GH 0 j N-2 UpSpWHU /* sélection d’un élément */
min <- i
3RXU j GH i+1 j N-1 UpSpWHU /* recherche du minimum */
6L t[ j ] < t[ min ] DORUV

min <- j
)LQVL

)LQSRXU

tmp <- t[ i ] /* échange */


t[ i ] <- t[ min ]
t[ min ] <- tmp
)LQSRXU

)LQ

Benoît Charroux - Tris - Septembre 98 - 5

Tri par insertion


Méthode :
on considère les éléments les uns après les autres en insérant chacun à sa place
parmi les éléments déjà triés.

20 6 1 3 1 7
6 20 1 3 1 7
1 6 20 3 1 7
1 3 6 20 1 7
1 1 3 6 20 7
1 1 3 6 7 20
Il faut :
• 1 boucle pour parcourir le tableau et sélectionner l’élément à insérer ;
• 1 boucle pour décaler les éléments plus grands que l’élément à insérer ;
• insérer l’élément.

Benoît Charroux - Tris - Septembre 98 - 6


Algorithme du tri par insertion

3URFpGXUH triInsertion( t: tab en entrée sortie )


$OJRULWKPH

'pEXW

9DULDEOHV i, j, mem: HQWLHU


3RXU i GH 1 j N-1 UpSpWHU /* sélection de l’élément à insérer*/
mem <- t[ i ]
j <- i
7DQWTXH j>0 HW t[j-1]>mem UpSpWHU/* décalage des éléments plus grands */

t[ j ] <- t[ j-1 ]
j <- j - 1
)LQWDQWTXH

t[ j ] <- mem /* insertion */


)LQSRXU

)LQ

Benoît Charroux - Tris - Septembre 98 - 7

Amélioration du tri par insertion


3URFpGXUH triInsertion( t: tab en entrée sortie )
$OJRULWKPH

'pEXW

...
7DQWTXH j>0 HW ... 5pSpWHU Le test j>0 qui évite les dépassements à
gauche du tableau est presque toujours vrai !
...
j <- j - 1
)LQWDQWTXH

...
)LQ

Placer une « sentinelle » : élément inférieur ou égale au minimum du tableau

-1 20 6 1 3 1 7

Benoît Charroux - Tris - Septembre 98 - 8


Tri à bulles
Méthode :
on parcours autant de fois le tableau en permutant 2 éléments adjacents mal classés
qu’il le faut pour que le tableau soit trié.

20 6 6 6 6 6 1 1 1 1 1
6 20 1 1 1 1 6 3 3 3 1
Tableau
prit 1 1 20 3 3 3 3 6 1 1 ... 3
dans ce 3 3 3 20 1 1 1 1 6 6 6
sens
1 1 1 1 20 7 7 7 7 7 7
7 7 7 7 7 20 20 20 20 20 20

5 passes 4 passes

Il faut :
• 1 boucle pour parcourir tout le tableau et sélectionner les éléments un à un ;
• 1 boucle pour permuter les éléments adjacents.
Benoît Charroux - Tris - Septembre 98 - 9

Algorithme du tri à bulles

3URFpGXUH triBulles( t: tab en entrée sortie )


$OJRULWKPH

'pEXW

9DULDEOHV i, j, temp: HQWLHU


3RXU i GH N-1 j 0 UpSpWHU /* sélection de l’élément à insérer*/
3RXUj GH 1 ji UpSpWHU /* décalage des éléments plus grands */
6L t[ j-1 ] > t[ j ] DORUV

tmp <- t[ j-1 ] /* échange */


t[ j-1 ] <- t[ j ]
t[j ] <- tmp
)LQVL

)LQSRXU

)LQSRXU

)LQ

Benoît Charroux - Tris - Septembre 98 - 10


Comparaison des performances des tris élémentaires
3URFpGXUH triSélection( t: tab … ) 3URFpGXUH triInsertion( t: tab … )
$OJRULWKPH $OJRULWKPH

'pEXW 'pEXW

3RXU i GH 0 j N-2 UpSpWHU 3RXU i GH 1 j N-1 UpSpWHU


3RXU j GH i+1 j N-1 UpSpWHU 7DQWTXH j>0 HW t[j-1]>mem UpSpWHU
)LQSRXU )LQWDQWTXH

)LQSRXU )LQSRXU

)LQ )LQ

3URFpGXUH triBulles( t: tab … )


Ces méthodes prennent de l’ordre de N2 étapes
$OJRULWKPH
pour trier N éléments :
'pEXW

3RXU i GH N-1 j 0 UpSpWHU • N petit ou éléments presque triés ;


3RXUj GH 1 ji UpSpWHU

)LQSRXU
• N grand et éléments dans un ordre
)LQSRXU
aléatoire.
)LQ

Benoît Charroux - Tris - Septembre 98 - 11

Performances du tri par sélection

Tri par sélection :


• nombre de comparaison de l’ordre de N2/2 ;
• nombre d’échanges de l’ordre de N.

3URFpGXUH triSélection( t: tab en entrée sortie )


$OJRULWKPH

'pEXW

3RXU i GH 0 j N-2 UpSpWHU /* boucle N-1 fois */


3RXU j GH i+1 j N-1 UpSpWHU /* boucle N-i fois */
6L t[ j ] < t[ min ] DORUV /* (N-1)+(N-2)+…+2+1=N(N-1)/2 comparaisons */
min <- j /* seule partie qui dépend des données */
)LQVL

)LQSRXU

... /* N-1 échanges */


)LQSRXU

)LQ

Benoît Charroux - Tris - Septembre 98 - 12


Performances du tri par insertion
Tri par insertion :
• nombre de comparaison de l’ordre de N2/4 ;
• nombre d’échanges de l’ordre de N2/8 ;
• linéaire si les données sont déjà triées.

Dans le pire des cas :


3URFpGXUH triInsertion( t: tab … ) • nombre de comparaisons -> N2/2
$OJRULWKPH • nombre d’échanges -> N2 /4
'pEXW

3RXU i GH 1 j N-1 UpSpWHU /* boucle N-1 fois */


mem <- t[ i ]
j <- i
7DQWTXH ... t[j-1]>mem UpSpWHU/* boucle i fois ⇒ 1+2+…+(N-1)=N(N-1)/2 */

t[ j ] <- t[ j-1 ] /* N(N-1)/2 « demi échanges » */


)LQWDQWTXH

)LQSRXU

)LQ

Benoît Charroux - Tris - Septembre 98 - 13

Performances du tri à bulles


Tri à bulles :
• nombre de comparaison de l’ordre de N2/2 ;
• nombre d’échanges de l’ordre de N2/2 ;
• 1 seule passe si le tableau est déjà trié.

3URFpGXUH triBulles( t: tab en entrée sortie )


$OJRULWKPH

'pEXW
Tableau trié en ordre inverse
3RXU i GH N-1 j 0 UpSpWHU /* boucle N fois */
3RXUj GH 1 ji UpSpWHU/* boucle i fois */

6L t[ j-1 ] > t[ j ] DORUV /* 1+2+…+N ≈ N /2 comparaisons au pire des cas */


2

... /* échanges = comparaisons ≈ N2/2 */


)LQVL

)LQSRXU

)LQSRXU

)LQ

Benoît Charroux - Tris - Septembre 98 - 14


Comparaison des tris
Tri par sélection : Tableaux de petites tailles :
• nombre de comparaison de l’ordre de N2/2 ; • sélection ;
• nombre d’échanges de l’ordre de N. • insertion ;
• bulles.
Tri par insertion :
• nombre de comparaison de l’ordre de N2/4 ;
Tableaux presque triés :
• nombre d’échanges de l’ordre de N2/2 ;
• sélection ;
• linéaire si les données sont déjà triées.
• insertion ;
Tri à bulles : • bulles.
• nombre de comparaison de l’ordre de N2/2 ;
• nombre d’échanges de l’ordre de N2/2 ; Tableaux avec de grands
enregistrements mais des
Tableaux de grandes tailles et aléatoires : clefs petites :
• sélection ; • sélection ;
• insertion ;
• insertion ;
• bulles.
• bulles.
Benoît Charroux - Tris - Septembre 98 - 15

Tri shell : amélioration du tri par insertion


Le tri par insertion :
• réaliser un tri par insertion sur
on considère les éléments les uns après
des éléments séparés par h cases
les autres en insérant chacun à sa place
parmi les éléments déjà triés. => faire moins de décalage :

3 2 23 1 20 6 0
3 2 23 1 20 6 0 ...
...
3 1 20 2 23 6 0
1 2 3 6 20 23 0

0 1 3 2 20 6 23
0 1 2 3 6 20 23

on obtient un tableau
entrelacé partiellement trié ;
Inconvénient : pour ramener un
élément de la fin vers la tête, il faut
• faire décroître h jusqu’à 1
décaler tous les éléments plus
grands. pour finir de trier le tableau.

Benoît Charroux - Tris - Septembre 98 - 16


Tri shell : amélioration du tri par insertion
Méthode :
• réaliser un tri par insertion sur des éléments distant de h cases ;
• faire décroître h.

43 21 8 65 6 1 3 34 7 20 11 51 54 27 9
h = 13 27 21 8 65 6 1 3 34 7 20 11 51 54 43 9
27 21 8 65 6 1 3 34 7 20 11 51 54 43 9
6 21 8 65 7 1 3 34 27 20 11 51 54 43 9
h=4 6 1 8 65 7 20 3 34 27 21 11 51 54 43 9
6 1 3 65 7 20 8 34 27 21 9 51 54 43 11
...
1 3 6 7 8 9 11 20 21 37 34 43 51 53 65

Le choix de h est empirique : le suite …, 364, 121, 40, 13, 4 et 1 est souvent utilisée.

Benoît Charroux - Tris - Septembre 98 - 17

3URFpGXUH triShell( t: tab … ) Algorithme du tri shell


$OJRULWKPH

'pEXW

9DULDEOHV i, j, h, mem: HQWLHU


h <- 1
7DQWTXH h <= N/9 UpSpWHU /* génère le premier de la suite */
h <- 3*h+1
)LQWDQWTXH

7DQWTXH h > 0 UpSpWHU /* pour toute la suite …364, 121, 40, 13, 4, 1*/
/* tri par insertion d’éléments distant de h cases */
h <- h/3
3RXU i GH h+1 j N-1 UpSpWHU
)LQWDQWTXH
mem <- t[ i ]
)LQ
j <- i
7DQWTXH j>h HW t[j-h]>mem UpSpWHU

t[ j ] <- t[ j-h ]
j <- j - h
)LQWDQWTXH

t[ j ] <- mem
)LQSRXU
Benoît Charroux - Tris - Septembre 98 - 18
Performances du tri shell

Tri shell :
• N3/2 comparaisons au maximum pour la suite 1,
4, 13, 40, … ;
• actuellement, on ne connaît pas la complexité
en temps de cet algorithme.

Méthode de choix dans de nombreuses application :

• commencer par utiliser cette méthode même sur des tableaux


relativement gros (- 5000 éléments) ;
• si les performances sont mauvaises, envisager une autre solution.

Benoît Charroux - Tris - Septembre 98 - 19

Tri rapide (quick sort)


Méthode diviser pour résoudre :
❶ choisir un seuil (pivot) ;
❷ mettre les éléments plus petit que le seuil à gauche du seuil et les éléments
plus grands à droite ;
❸ recommencer séparément sur les parties droite et gauche.

❶ 20 6 1 3 1 7
❷ 1 6 1 3 7 20
❸ 1 6 1 3
❶ 1 6 1 3
❷ 1 1 3 6

Il faut :
• partitionner selon un pivot ;
• recommencer sur les partitions (récursion).
Benoît Charroux - Tris - Septembre 98 - 20
Algorithme du tri rapide

3URFpGXUH triRapide( t: tab en entrée sortie, g: HQWLHU, d: HQWLHU )


$OJRULWKPH

'pEXW

9DULDEOH p: HQWLHU
6L d > g DORUV
p <- partitionnement( t, g, d ) /* p = pivot */
triRapide( t, g, p-1 ) /* trier partie gauche */
triRapide( t, p+1, d ) /* trier partie droite */
)LQVL

)LQ

Benoît Charroux - Tris - Septembre 98 - 21

Algorithme du tri rapide 20 6 1 11 2 7


)RQFWLRQ partitionnement( t: tab, g: HQWLHU, d: HQWLHU ): HQWLHU
$OJRULWKPH

'pEXW
2 6 1 11 20 7
9DULDEOH i, j, p, tmp: HQWLHU
p <- t|d] /* pivot = élément de droite */
i <- g-1 /* i = curseur partant de la gauche */
j <- d /* j = curseur partant de la droite */
5pSpWHU

5pSpWHU /* recherche à partir de la gauche ...*/


i <- i+1
7DQWTXHt[ i ] < p /* du premier élément > pivot */
5pSpWHU /* recherche à partir de la droite ...*/
j <- j-1
7DQWTXH j>i HWt[ j ] > p /* du premier élément < pivot */
6Li >= j DORUV /* si les curseurs se rejoignent … */
EUHDN /* la partition est faite */
)LQVL

tmp <- t[i] t[i] <- t[j] t[j] <- tmp /* échange des éléments aux curseurs */
6DQVFRQGLWLRQ

tmp <- t[i] t[i] <- t[d] t[d] <- tmp /* déplacement du pivot à sa place */
UHWRXU i
)LQ

Benoît Charroux - Tris - Septembre 98 - 22


Performance du tri rapide
Tri le plus employé :
• relativement simple ;
• de l’ordre de NlogN opérations en moyenne pour trier N éléments ;
• de l’ordre de N2 opérations dans le pire des cas : tableaux simples
(déjà triés par exemple) ;

1 2 6 7 11 20
1 2 6 7 11
1 2 6 7
1 2 6
1 2
1

• ∃ méthodes pour améliorer les performances (partitionnement par la


médiane).

Benoît Charroux - Tris - Septembre 98 - 23

Tri par fusion (merge sort)

20 6 1 3 10 8 15 12
20 6 1 3 10 8 15 12
Division :
20 6 1 3 10 8 15 12
20 6 1 3 10 8 15 12

6 20
1 3
1 3 6 20
Fusion : 8 10
12 15
8 10 12 15
1 3 6 8 10 12 15 20

Benoît Charroux - Tris - Septembre 98 - 24


Diviser

3URFpGXUH triFusion( t: tab en entrée sortie, g: HQWLHU, d: HQWLHU )


$OJRULWKPH

'pEXW

9DULDEOH m: HQWLHU
6L d > g DORUV
m <- (g+d) / 2
triFusion( t, g, m ) /* trier partie gauche */
triFusion( t, m+1, d ) /* trier partie droite */
… /* fusionner */
)LQVL

)LQ

Benoît Charroux - Tris - Septembre 98 - 25

Fusionner à l’aide d’un tableau intermédiaire 1/2

• Remplir le tableau intermédiaire s.

g m d
tableau t : 1 3 6 20 8 10 12 15

tableau intermédiaire s : 1 3 6 20 15 12 10 8

Partie miroir de t
...
3RXU i GH m j g UpSpWHU
s[ i ] <- t[ i ]
)LQSRXU

3RXU j GH m+1 j d UpSpWHU


s[ d+m+1-j ] <- t[ j ]
)LQSRXU

...
Benoît Charroux - Tris - Septembre 98 - 26
Fusionner à l’aide d’un tableau intermédiaire

• Comparer les éléments de s deux à deux pour les fusionner dans t.



k<-g i<-g j<-d

7DQWTXH k <= d UpSpWHU /* parcours de t */

6L s[i] < s[j] DORUV



t[k] <- s[i] ❹
i <- i+1 ❺
6LQRQ

i, k ❼ j
t[k] <- s[j]
j <- j-1 tableau s : 1 3 6 20 15 12 10 8
)LQVL g d
k <- k+1
)LQWDQWTXH
tableau t : 1 3 6 8 10 12 15 20

Benoît Charroux - Tris - Septembre 98 - 27

Performance du tri par fusion

Tri par fusion :

• nombre de comparaison de l’ordre NlogN pour trier N éléments ;

• place mémoire supplémentaire proportionnelle à N ;

• tri idéal pour pour les listes chaînées (accès séquentiel) en changeant
la partie fusion de l’algorithme.

Benoît Charroux - Tris - Septembre 98 - 28


Tri par tas (heap sort)
20
Transformer en tas
20 6 1 3 10 8 15 10 15
tel que père > fils ∀ père
3 6 1 8
❶ Transformer en tas
❷ Trier :
• supprimer le maximum et rétablir la condition père > fils ∀ père ;

20

10 15 15

3 6 1 8 10 8

3 6 1
20

• itérer le processus tant que le tableau n’est pas trié.

Benoît Charroux - Tris - Septembre 98 - 29

Transformer en tas Si père à i :


20 6 1 3 10 8 15 • fils 1 à 2*i+1
• fils 2 à 2*i+2

20 0 1 2 3 4 5 6

10 15
⇔ 20 10 15 3 6 1 8

2*2+1
3 6 1 8 2*2+2

20 Insérer 15 ? ❶ chercher le père :


0 1 2 3 4 5 6
10 8

3 6 1 15
⇔ 20 10 8 3 6 1 15
6/2-1
20 ❷ permuter si nécessaire :
0 1 2 3 4 5 6

10 15
20 10 15 3 6 1 8
3 6 1 8
Benoît Charroux - Tris - Septembre 98 - 30
Transformer en tas
❶ chercher le père :
0 1 2 3 4 5 6
3URFpGXUH insertionTas( t: tab ..., v: HQWLHU )
$OJRULWKPH
20 10 8 3 6 1 15
'pEXW
6/2-1
9DULDEOH p: HQWLHU
N <- N + 1
t[ N ] <- v /* ajout nouveau en fin de tableau */
i <- N
7DQWTXHi<=1 et t[ i/2-1 ] <= v UpSpWHU /* tant que père <= nouveau */
t[ i ] <- t[ i/2-1 ] /* fait descendre le père */
i <- i/2-1 /* père suivant */
)LQWDQWTXH

t[ i ] <- v /* positionne nouveau */


)LQ
❷ permuter si nécessaire :
0 1 2 3 4 5 6
20 10 15 3 6 1 8

Benoît Charroux - Tris - Septembre 98 - 31

Trier
20
15
10 15
10 8
3 6 1 8
3 6 1
20

3URFpGXUHW riParTas( t: tab en entrée sortie )


$OJRULWKPH

'pEXW

9DULDEOH i: HQWLHU
3RXUiGH1jNUpSpWHU

insertionTas( t, t[ i ] ) /* transformer en tas */


)LQSRXU

3RXU GH i Nj0UpSpWHU


t[ i ] <- supprimerMax( t ) /* trier */
)LQSRXU

)LQ
Benoît Charroux - Tris - Septembre 98 - 32
Supprimer le maximum 1/2
20

10 15

3 6 1 8

20

)RQFWLRQ supprimerMax( t: tab en entrée sortie ) : HQWLHU


$OJRULWKPH
0 1 2 3 4 5 6
'pEXW

9DULDEOH i, j, v, max: HQWLHU 20 10 15 3 6 1 8


max <- t[ 1 ]
t[ 1 ] <- t| N ] /* place le dernier élément en tête */
N <- N-1 /* supprime la dernière case (le max) */
… /* reconstruire le tas */
UHWRXU max

)LQ

Benoît Charroux - Tris - Septembre 98 - 33

Supprimer le maximum 2/2


0 1 2 3 4 5 6
15
8 10 15 3 6 1
10 8
0 1 2 3 4 5 6
/* reconstruire le tas */
3 6 1 15 10 8 3 6 1
v <- t[ 1 ]
7DQWTXH i <= N/2 UpSpWHU

j <- i+i /* j est le premier fils de i */


6L j<N et t[j]<t[j+1] DORUV /* si le deuxième fils est plus grand … */
j <- j+1 /* on le garde */
)LQVL

6L v >= t[ j ] DORUV
EUHDN

)LQVL

t[ i ] <- t[ j ] /* échange avec le plus grand des fils */


i <- j /* y a-t’il d’autres fils ? */
)LQWDQWTXH

t[ i ] <- v
Benoît Charroux - Tris - Septembre 98 - 34
Performance du tri par tas

Tri par tas :

• nécessite de l ’ordre de NlogN étapes pour trier N éléments ;

• pas de place mémoire supplémentaire ;

• en moyenne deux fois plus lent que le tri rapide.

Benoît Charroux - Tris - Septembre 98 - 35

Comparaison des tris

Tri shell : Le plus employé :


• de l’ordre de N3/2 comparaisons. • tri rapide

Tri rapide : Le plus simple sur des


• de l’ordre de NlogN opérations ; fichiers relativement gros
(-5000 éléments) :
• de l’ordre de N2 opérations dans le pire des cas.
• tri shell
Tri par fusion :
Tri de listes chaînées :
• nombre de comparaison de l’ordre NlogN ;
• place mémoire supplémentaire proportionnelle à N. • tri par fusion

Tri par tas : Tri de fichiers


• nécessite de l’ordre de NlogN étapes ; partiellement triés :
• en moyenne deux fois plus lent que le tri rapide. • tri par tas

Benoît Charroux - Tris - Septembre 98 - 36

Vous aimerez peut-être aussi