Algorithmes de tri - UQAC
Algorithmes de tri - UQAC
Algorithmes de tri - UQAC
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
<strong>Algorithmes</strong> <strong>de</strong> <strong>tri</strong><br />
1
l’utilité <strong>de</strong>s <strong>tri</strong>s<br />
Problématique:<br />
Un grand nombre <strong>de</strong> problèmes réels ont recours à la<br />
recherche d’éléments dans un vecteur (tableau). Cette<br />
recherche <strong>de</strong>vient quasiment impossible lorsqu’elle<br />
s’effectue dans un vecteur désordonné, d’où le besoin <strong>de</strong><br />
<strong>tri</strong>er les vecteurs avant d’y effectuer un traitement.<br />
Exemples:<br />
• Les mots dans un dictionnaire.<br />
• Fichiers dans un répertoire <strong>de</strong> PC.<br />
• Les CD répertoriés dans un magasin <strong>de</strong> musique.<br />
• Les sigles <strong>de</strong>s cours <strong>de</strong> Poly offert pour une session.<br />
2
Définitions<br />
Tri interne : se dit d'un algorithme qui<br />
n'utilise pas <strong>de</strong> tableau temporaire pour<br />
effectuer le <strong>tri</strong>.<br />
Tri externe : se dit d'un algorithme <strong>de</strong> <strong>tri</strong><br />
qui nécessite l'utilisation d'un tableau<br />
temporaire.<br />
3
II – Les <strong>tri</strong>s simples<br />
• Tri par sélection s<br />
• Tri bulle<br />
• Tri par insertion<br />
4
Tri par sélections<br />
Principe :<br />
• Cette technique consiste à parcourir<br />
séquentiellement le vecteur à <strong>tri</strong>er. À l'itération<br />
i, la plus petite valeur du tableau est échangée<br />
avec la valeur située dans la case d'indice i.<br />
5
Exemple d’exd<br />
exécution du <strong>tri</strong> par<br />
sélection<br />
min = [1] [2]<br />
[3] [4] [0]<br />
i = 0123<br />
10<br />
2<br />
7<br />
15<br />
8<br />
0 1 2 3 4 i<br />
6
Programmation du <strong>tri</strong> par sélections<br />
template<br />
void TriSelection( vector& Tableau, int n)<br />
{<br />
int i, j, min;<br />
T Tmp;<br />
for ( i=0 ; i
Tri en bulle<br />
Principe :<br />
• Les petits éléments du tableau « remontent »<br />
(comme <strong>de</strong>s bulles) vers le début du tableau pour<br />
atteindre leur position finale. Les plus « légers »<br />
remontent le plus rapi<strong>de</strong>ment. Une fois tous les<br />
éléments remontés, le tableau est <strong>tri</strong>é.<br />
8
Exemple d’exd<br />
exécution du <strong>tri</strong> en bulle<br />
: comparaison <strong>de</strong><br />
<strong>de</strong>ux éléments<br />
10<br />
2<br />
7<br />
15<br />
8<br />
Position <strong>de</strong> i<br />
0 1 2 3 4 i<br />
9
Programmation du <strong>tri</strong> en bulle<br />
template<br />
void TriBulle(vector& Tableau, , int n)<br />
{<br />
int i,j;<br />
T Tmp;<br />
for ( i=0; ii; j--j<br />
--)<br />
if ( Tableau[j-1]> Tableau[j])<br />
{<br />
Tmp = Tableau[j-1];<br />
Tableau[j-1] = Tableau[j];<br />
Tableau[j] = Tmp;<br />
}<br />
}<br />
10
Tri par insertion<br />
Principe :<br />
• Cette stratégie est semblable à la métho<strong>de</strong><br />
qu'utilise naturellement un joueur <strong>de</strong> cartes pour<br />
organiser sa main. À chaque étape, une partie<br />
du tableau est déjà ordonnée et une nouvelle<br />
valeur est insérée à l'endroit approprié.<br />
11
Exemple d’exd<br />
exécution par insertion<br />
10<br />
2<br />
7<br />
15<br />
8<br />
0 1 2 3 4 i<br />
12
Programmation du <strong>tri</strong> par insertion<br />
template < class T><br />
void TriInsertion(vector& Tableau, int n)<br />
{<br />
int i,j;<br />
T Tmp;<br />
for ( i=1;i
Analyse <strong>de</strong>s <strong>tri</strong>s simples<br />
Meilleur cas: tableau déjà <strong>tri</strong>é<br />
1 3 5 7 9 10 13 18 21 25<br />
Cas moyen: tableau aléatoire<br />
7 10 21 9 1 25 18 3 5 13<br />
Pire cas: tableau <strong>tri</strong>é à l’envers<br />
25 21 18 13 10 9 7 5 3 1<br />
14
Comparaison <strong>de</strong>s <strong>tri</strong>s simples<br />
Pire cas Cas moyen Meilleur cas<br />
Tri par sélection<br />
Tri en bulle<br />
Tri par insertion<br />
O ( n<br />
2 ) (<br />
2<br />
O n ) (<br />
2<br />
O n )<br />
O ( n<br />
2 ) (<br />
2<br />
O n ) (<br />
2<br />
O n )<br />
O ( n<br />
2 ) (<br />
2<br />
n )<br />
O O( n)<br />
15
mergesort<br />
Problématique :<br />
<br />
Le <strong>tri</strong> est effectué en utilisant la technique <strong>de</strong> diviser-etconquérir,<br />
en divisant le problème en <strong>de</strong>ux sousproblèmes<br />
<strong>de</strong> complexité θ ( n)<br />
résolus récursivement,<br />
offrant une complexité globale <strong>de</strong><br />
L'algorithme <strong>de</strong> <strong>tri</strong> Mergesort :<br />
( nlog2 n )<br />
1. Si le nombre d’éléments à <strong>tri</strong>er == (0 ou 1), retourner.<br />
2. Trier récursivement la première et <strong>de</strong>uxième moitié<br />
séparément.<br />
3. Regrouper les <strong>de</strong>ux parties <strong>tri</strong>ées dans un nouveau groupe<br />
<strong>tri</strong>é.<br />
θ<br />
16
MergeSort<br />
1 13 24 26 2 15 27 38<br />
Actr<br />
Bctr<br />
Cctr<br />
17
La fonction Mergesort<br />
// Routine interne : Tableau: le vecteur d’éd<br />
’éléments<br />
// tmpTab: vecteur temporaire pour les résultatsr<br />
// left, right: indices gauche et droit <strong>de</strong>s tableaux<br />
template <br />
void mergeSort(vector& Tableau, vector& tmpTab,<br />
int left, int right)<br />
{<br />
if (left < right)<br />
{<br />
int center = (left+right)/2;<br />
mergeSort(Tableau, tmpTab, left, center)<br />
mergeSort(Tableau, tmpTab, center+1, right);<br />
merge(Tableau, tmpTab, left, center+1, right);<br />
}<br />
}<br />
template // Fonction principale<br />
void mergeSort(vector& Tableau)<br />
{<br />
vector tmpTab(Tableau.size());<br />
mergeSort(Tableau,tmpTab,0,Tableau.size()-1);<br />
}<br />
18
La fonction Merge<br />
// Routine interne : Tableau: le vecteur d’éd<br />
’éléments<br />
// tmpTab: vecteur pour les résultats r<br />
du merge<br />
// leftPos: indice gauche du tableau<br />
// rightPos: indice du début d<br />
<strong>de</strong> la 2ieme <strong>de</strong>mi<br />
// rightEnd: indice droit du tableau<br />
template <br />
void merge(vector& Tableau, vector& tmpTab, int leftPos,<br />
int rightPos, int rightEnd)<br />
{<br />
int leftEnd = rightPos-1;<br />
int tmpPos = leftPos;<br />
int numElements = rightEnd – leftPos +1;<br />
//Boucle principale<br />
while( leftPos
La fonction Merge<br />
. . .<br />
while(leftPos
Le <strong>tri</strong> rapi<strong>de</strong> (Quicksort(<br />
Quicksort)<br />
Idée e générale g<br />
:<br />
Dans cet algorithme, l'exécution du <strong>tri</strong> est simplement délégud<br />
guée à une<br />
série d'appels récursifs. r<br />
Une fonction <strong>de</strong> partitionnement est d'abord<br />
appelée. e. Cette fonction choisit arbitrairement un pivot qui est utilisé<br />
pour subdiviser le tableau en <strong>de</strong>ux parties:<br />
1. une partie <strong>de</strong> gauche oùo<br />
tous les éléments ont une valeur plus petite<br />
ou égale au pivot;<br />
2. une partie <strong>de</strong> droite oùo<br />
tous les éléments ont une valeur plus gran<strong>de</strong><br />
ou égale au pivot.<br />
Par la suite, les <strong>de</strong>ux parties ainsi obtenues sont <strong>tri</strong>ées par <strong>de</strong>ux appels<br />
récursifs<br />
à la fonction <strong>de</strong> <strong>tri</strong> rapi<strong>de</strong>.<br />
En plus <strong>de</strong> la fonction principale <strong>de</strong> <strong>tri</strong> rapi<strong>de</strong>, une autre fonction est<br />
donc requise: celle qui procè<strong>de</strong><br />
à la partition du tableau.<br />
21
Quicksort : choix du pivot<br />
premier élément ?<br />
élément aléatoire?<br />
<strong>de</strong>rnier élément?<br />
élément médian?<br />
…. 7 2 9 6 1 5 4 3 …..<br />
22
La fonction Quicksort<br />
template <br />
void QuickSort(vector& tableau, int inf,<br />
int sup)<br />
{<br />
int milieu;<br />
if (sup>inf) // s'il y a au moins 2<br />
éléments<br />
{<br />
milieu = Partition(tableau, inf, sup);<br />
}<br />
}<br />
// <strong>tri</strong>er la partie <strong>de</strong> gauche<br />
QuickSort(tableau, inf, milieu);<br />
// <strong>tri</strong>er la partie <strong>de</strong> droite<br />
QuickSort(tableau, milieu+1, sup);<br />
23
Exemple d’exd<br />
exécution <strong>de</strong> Partition<br />
i<br />
Premier Pivot =<br />
appel<br />
Tab[2] = 5<br />
Quicksort(a,0,4)<br />
j<br />
11<br />
7<br />
5<br />
2<br />
9<br />
0 1 2 3 4 i<br />
24
La fonction Partition<br />
template <br />
int Partition(vector& tableau, int inf, int sup)<br />
{<br />
T pivot, tempo;<br />
int i,j;<br />
pivot = tableau[(sup+inf)/2];<br />
i = inf-1;<br />
j = sup+1;<br />
while ( i
Complexité du Quicksort<br />
Cas moyen et meilleur cas<br />
Complexité du Quicksort dans le cas moyen<br />
et dans le meilleur cas θ( nlog2 n ).<br />
Pire cas<br />
Complexité du Quicksort dans le pire cas:<br />
θ<br />
2<br />
( n )<br />
26