// décalage des valeurs du tableau dans l'intervalle 0..val_max-val_min
for (int i=0; i < size; i++) {
tab1[i] -= val_min;
}
for (int pos=0;pos<nb_bits;pos++) {
bucket_0(size, tab1, tab2, pos);
bucket_1(size, tab1, tab2, pos);
swap_ptr(&tab1, &tab2);
}
// décalage inverse dans l'intervalle val_min..val_max
for (int i=0;i<size;i++) {
tab1[i] += val_min;
}
if (tab1 != tab) {
for (int i=0;i<size;i++) {
tab[i] = tab1[i];
}
}
}
``` -->
<!-- # Complexité
L'algorithme implémenté précédemment nécessite un certain nombre d'opérations lié à la taille du tableau.
Voici une liste de parcours utilitaires de tableau:
1. Recherche de la valeur minimum ```val_min```
2. Recherche de la valeur maximum ```val_max```
3. Décalage des valeurs dans l'intervalle ```0..val_max-val_min```
4. Décalage inverse pour revenir dans l'intervalle ```val_min..val_max```
5. Copie éventuelle du tableau temporaire dans le tableau originel
On a donc un nombre de parcours fixe (4 ou 5) qui se font en $\mathcal{O}(N)$ où $N$ est la taille du tableau.
La partie du tri à proprement parler est une boucle sur le nombre de bits *b* de ```val_min..val_max```.
A chaque passage à travers la boucle, on parcourt 2 fois le tableau: la 1ère fois pour s'occuper des éléments dont le bit courant à 0; la 2ème pour ceux dont le bit courant est à 1.
A noter que le nombre d'opérations est de l'ordre de *b* pour la lecture d'un bit et constant pour la fonction ```swap_ptr()```.
Ainsi, la complexité du tri par base est $\mathcal{O}(b\cdot N)$. -->
# Tri par fusion (merge sort)
* Tri par comparaison.
...
...
@@ -421,7 +321,8 @@ Ainsi, la complexité du tri par base est $\mathcal{O}(b\cdot N)$. -->
* Parcours du tableau et comparaison des éléments consécutifs:
- Si deux éléments consécutifs ne sont pas dans l'ordre, ils sont échangés.
* On recommence depuis le début du tableau jusqu'à avoir plus d'échanges à
faire.
## Que peut-on dire sur le dernier élément du tableau après un parcours?
. . .
* Le plus grand élément est **à la fin** du tableau.
* Plus besoin de le traiter.
* A chaque parcours on s'arrête un élément plus tôt.
# Tri à bulle (2/4)
## Exemple

# Tri à bulle (3/4)
## Exercice: écrire l'algorithme (poster le résultat sur matrix)
. . .
```C
rien tri_a_bulles(entier tableau[])
pour i de longueur(tableau)-1 à 1:
trié = vrai
pour j de 0 à i-1:
si (tableau[j] > tableau[j+1])
échanger(array[j], array[j+1])
trié = faux
si trié
retourner
```
# Tri à bulle (4/4)
## Quelle est la complexité du tri à bulles?
. . .
* Dans le meilleurs des cas:
* Le tableau est déjà trié: $\mathcal{O}(N)$ comparaisons.
* Dans le pire des cas, $N\cdot (N-1)/2\sim\mathcal{O}(N^2)$:
$$
\sum_{i=1}^{N-1}i\mbox{ comparaison et }3\sum_{i=1}^{N-1}i \mbox{ affectations
(swap)}\Rightarrow \mathcal{O}(N^2).
$$
* En moyenne, $\mathcal{O}(N^2)$ ($N^2/2$ comparaisons).
# L'algorithme à la main
## Exercice *sur papier*
* Trier par tri à bulles le tableau `[5, -2, 1, 3, 10, 15, 7, 4]`
```C
```
# Tri par insertion (1/3)
## But
* trier un tableau par ordre croissant
## Algorithme
Prendre un élément du tableau et le mettre à sa place parmi les éléments déjà
triés du tableau.

# Tri par insertion (2/3)
## Exercice: Proposer un algorithme (en C)
. . .
```C
void tri_insertion(int N, int tab[N]) {
for (int i = 1; i < N; i++) {
int tmp = tab[i];
int pos = i;
while (pos > 0 && tab[pos - 1] > tmp) {
tab[pos] = tab[pos - 1];
pos = pos - 1;
}
tab[pos] = tmp;
}
}
```
# Tri par insertion (3/3)
## Question: Quelle est la complexité?
. . .
* Parcours de tous les éléments ($N-1$ passages dans la boucle)
* Placer: en moyenne $i$ comparaisons et affectations à l'étape $i$
* Moyenne: $\mathcal{O}(N^2)$
. . .
* Pire des cas, liste triée à l'envers: $\mathcal{O}(N^2)$
* Meilleurs des cas, liste déjà triée: $\mathcal{O}(N)$
# L'algorithme à la main
## Exercice *sur papier*
* Trier par insertion le tableau `[5, -2, 1, 3, 10]`
```C
```
# Complexité algorithmique du radix-sort (1/2)
## Pseudo-code
```python
rienradix_sort(entiertaille,entiertab[taille]):
# initialisation
entierval_min=valeur_min(taille,tab)
entierval_max=valeur_max(taille,tab)
decaler(taille,tab,val_min)
entiernb_bits=nombre_de_bits(val_max-val_min)
# algo
entiertab_tmp[taille]
pourposde0ànb_bits:
alveole_0(taille,tab,tab_tmp,pos)# 0 -> taille
alveole_1(taille,tab,tab_tmp,pos)# taille -> 0
echanger(tab,tab_tmp)
# post-traitement
decaler(taille,tab,-val_min)
```
# Complexité algorithmique du radix-sort (2/2)
\footnotesize
<!-- Voici une liste de parcours utilitaires de tableau:
1. Recherche de la valeur minimum ```val_min```
2. Recherche de la valeur maximum ```val_max```
3. Décalage des valeurs dans l'intervalle ```0..val_max-val_min```
4. Décalage inverse pour revenir dans l'intervalle ```val_min..val_max```
5. Copie éventuelle du tableau temporaire dans le tableau originel
On a donc un nombre de parcours fixe (4 ou 5) qui se font en $\mathcal{O}(N)$ où $N$ est la taille du tableau.
La partie du tri à proprement parler est une boucle sur le nombre de bits *b* de ```val_min..val_max```.
A chaque passage à travers la boucle, on parcourt 2 fois le tableau: la 1ère fois pour s'occuper des éléments dont le bit courant à 0; la 2ème pour ceux dont le bit courant est à 1.
A noter que le nombre d'opérations est de l'ordre de *b* pour la lecture d'un bit et constant pour la fonction ```swap_ptr()```.
Ainsi, la complexité du tri par base est $\mathcal{O}(b\cdot N)$. -->