Algorithmes de tri (1/2)
Problématique : étant donné une structure linéaire (tableau, liste,
etc) contenant des valeurs d'un type ordonné, il faut trier les
éléments en ordre croissant (ou décroissant).
Il existe des dizaines d'algorithmes répondant à ce problème,
utilisant quelques principes de base auxquels on ajoute des
variantes
On peut distinguer :
les tris internes qui trient les éléments dans la structure qui les contient
(tableau, liste, ...) ou au pire utilise une structure annexe de même type
les tris externes utilisés lorsque la quantité d'éléments à trier est telle qu'ils ne
tiennent pas en mémoire vive et qu'il faut stocker des éléments dans des
fichiers ou des tables de bases de données
Algorithmes de tri (2/2)
Propriétés des algorithmes de tri :
complexité en temps et en espace
stabilité : l'algorithme ne modifie pas l'ordre initial des éléments égaux par
comparaison
tri sur place ou pas : l'algorithme n'utilise pas de mémoire supplémentaire
(hormis éventuellement quelques indices de boucle ou booléens), les
éléments sont triés directement dans la structure de données
La plupart des algorithmes de tri utilisent la comparaison
d'éléments 2 à 2
on montre que le nombre minimum de comparaisons à effectuer est nlog(n) si
n est la taille de la structure. Les algorithmes en O(n2) sont donc peu
efficaces, ceux au pire en O(nlog(n)) sont optimaux
il existe des tris linéaires, mais ils n'utilisent pas la comparaison et sont limités
à des cas très particuliers (tris de nombres dont on connait des propriétés
statistiques)
Tri à bulle (1/7)
Principe du tri à bulle (bubble sort) : l'élément le plus grand
remonte au bout du tableau, comme une bulle de champagne,
puis on recommence pour que le deuxième plus grand remonte,
etc. L'écriture de l'algorithme s'inspire de l'algorithme séquentiel
qui vérifie si un tableau est trié.
Algorithme : i désigne la dernière case à traiter
fonction sans retour triBulle(entier[] tab){
entier i,j,temp;
début
pour (i allant de tab.longueur-2 à 1 pas -1) faire
pour (j allant de 0 à i pas 1) faire
si (tab[j] > tab[j+1]) alors
temp <- tab[j];
tab[j] <- tab[j+1];
tab[j+1] <- temp;
finsi
finpour
finpour
fin
Tri à bulle (2/7)
Exemple : trier en ordre croissant le tableau suivant
701 | 17 | 2 | 268 | 415 | 45 | 45 | 102
17 | 701 | 2 | 268 | 415 | 45 | 45 | 102
17 | 2 | 701 | 268 | 415 | 45 | 45 | 102
17 | 2 | 268 | 701 | 415 | 45 | 45 | 102
17 | 2 | 268 | 415 | 701 | 45 | 45 | 102
17 | 2 | 268 | 415 | 45 | 701 | 45 | 102
17 | 2 | 268 | 415 | 45 | 45 | 701 | 102
17 | 2 | 268 | 415 | 45 | 45 | 102 | 701
premier tour de la première boucle (sur i)
j=0
j=1
j=2
j=3
j=4
j=5
j=6
Tri à bulle (3/7)
2 | 17 | 268 | 45 | 45 | 102 | 415 | 701
deuxième tour de la première boucle (sur i)
2 | 17 | 45 | 45 | 102 | 268 | 415 | 701
troisième tour de la première boucle (sur i)
2 | 17 | 45 | 45 | 102 | 268 | 415 | 701
quatrième tour de la première boucle (sur i)
Problème : l'algorithme va faire 3 tours supplémentaires
de la boucle sur i, inutilement
Tri à bulle (4/7)
Complexité du tri à bulle en fonction de la taille n du tableau :
la remontée du plus grand élément utilise (n-1) comparaisons, la remontée du
deuxième plus grand utilise (n-2), etc. La complexité sera donc toujours
proportionnelle à (n-1)+(n-2)+...+1 = n*(n-1)/2 soit O(n2).
Le tri à bulle est en place et l'algorithme donné ici est stable (il
serait instable si on utilisait au lieu de >)
Une amélioration possible du tri bulle consiste à utiliser une
variable booléenne drapeau qui permet de stopper le tri si plus
aucune permutation n'a lieu
Tri à bulle (5/7)
Remarques :
la complexité au pire et en moyenne reste en O(n2) mais est linéaire au mieux
cette amélioration n'est efficace que si le tableau est déjà « un peu » trié et
qu'il devient trié « assez vite »
fonction sans retour triBulle(entier[] tab){
entier i,j,temp;
booleen b;
début
b <- faux;
i <- tab.longueur-2;
tantque ((non b) et (i > 0)) faire
b <- vrai;
pour (j allant de 0 à i pas 1) faire
si (tab[j] > tab[j+1]) alors
temp <- tab[j];
tab[j] <- tab[j+1];
tab[j+1] <- temp;
b <- faux;
finsi
finpour
i <- i-1;
fintantque
fin
Tri à bulle (6/7)
Une autre amélioration possible du tri bulle est le tri
Boustrophedon (du nom des écritures qui changent de sens à
chaque ligne) :
on parcourt le tableau de gauche à droite, en faisant remonter l'élément le
plus grand
on redescend le tableau de droite à gauche, en faisant descendre le plus petit
on recommence en ignorant les 2 éléments déjà triés
la complexité au pire et en moyenne est toujours en O(n2) mais est réduite du
fait qu'on peut exploiter les bonnes positions des petits éléments comme des
plus grands
Tri à bulle (7/7)
Tri par la méthode du tri à bulle de tableaux d'entiers générés aléatoirement
Tri sélection (1/3)
Principe du tri sélection (ou tri par extraction) : on parcourt le
tableau pour trouver le plus grand élément, et une fois arrivé au
bout du tableau on y place cet élément par permutation. Puis on
recommence sur le reste du tableau.
Algorithme : i désigne la dernière case à traiter
fonction sans retour triSelection(entier[] tab){
entier i,j,temp,pg;
debut
i <- tab.longueur-1;
tanque (i > 0) faire
pg <- 0;
pour (j allant de 0 à i pas 1) faire
si (tab[j] > tab[pg]) alors
pg <- j;
finsi
finpour
temp <- tab[pg];
tab[pg] <- tab[i];
tab[i] <- temp;
i <- i-1;
fintantque
fin
1 / 12 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 !