Algorithme de tri en C
Tri à bulles
Le tri à bulles (Bubble Sort) est un algorithme de tri simple. Il parcourt de façon répétée la liste à trier, en comparant deux éléments à la fois, et les échange s'ils sont dans le mauvais ordre (par exemple du plus grand au plus petit, ou de la première lettre de A à Z).
Démonstration du processus :

Exemple
#include <stdio.h>
void bubble_sort(int arr[], int len);
int main() {
int arr[] = { 22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70 };
int len = sizeof(arr) / sizeof(arr[0]);
bubble_sort(arr, len);
for (int i = 0; i < len; i++) {
printf("%d ", arr[i]);
}
return 0;
}
void bubble_sort(int arr[], int len) {
for (int i = 0; i < len - 1; i++) {
for (int j = 0; j < len - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
Tri par sélection
Le tri par sélection est un algorithme de tri simple et intuitif. Son principe de fonctionnement est le suivant. Tout d'abord, trouvez le plus petit (ou le plus grand) élément dans la séquence non triée et placez-le au début de la séquence triée. Ensuite, continuez à trouver le plus petit (ou le plus grand) élément parmi les éléments non triés restants et placez-le à la fin de la séquence triée. Et ainsi de suite, jusqu'à ce que tous les éléments soient triés.
Démonstration du processus :


Exemple
#include <stdio.h>
void selection_sort(int a[], int len);
int main() {
int arr[] = { 22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70 };
int len = sizeof(arr) / sizeof(arr[0]);
selection_sort(arr, len);
for (int i = 0; i < len; i++) {
printf("%d ", arr[i]);
}
return 0;
}
void selection_sort(int a[], int len) {
for (int i = 0; i < len - 1; i++) {
int min = i;
for (int j = i + 1; j < len; j++) {
if (a[j] < a[min]) {
min = j;
}
}
if (min != i) {
int temp = a[min];
a[min] = a[i];
a[i] = temp;
}
}
}
Tri par insertion
Tri par insertion (anglais : Insertion Sort) est un algorithme de tri simple et intuitif. Son principe de fonctionnement consiste à construire une séquence ordonnée. Pour les données non triées, parcourir de l'arrière vers l'avant la séquence triée, trouver la position appropriée et l'insérer. Dans la mise en œuvre, le tri par insertion adopte généralement un tri en place (c'est-à-dire un tri qui ne nécessite que {\displaystyle O(1)} {\displaystyle O(1)} d'espace supplémentaire). Par conséquent, lors du processus de balayage de l'arrière vers l'avant, il est nécessaire de déplacer de manière répétée les éléments triés vers l'arrière, étape par étape.
Décaler pour faire de la place au nouvel élément.
Démonstration du processus :

Exemple
#include <stdio.h>
void insertion_sort(int arr[], int len);
int main() {
int arr[] = { 22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70 };
int len = sizeof(arr) / sizeof(arr[0]);
insertion_sort(arr, len);
for (int i = 0; i < len; i++) {
printf("%d ", arr[i]);
}
return 0;
}
void insertion_sort(int arr[], int len) {
for (int i = 1; i < len; i++) {
int temp = arr[i];
int j = i;
while (j > 0 && arr[j - 1] > temp) {
arr[j] = arr[j - 1];
j--;
}
arr[j] = temp;
}
}
Tri de Shell
Le tri de Shell, également appelé algorithme de tri par incréments décroissants, est une version améliorée plus efficace du tri par insertion. Le tri de Shell est un algorithme de tri instable.
Le tri de Shell propose des améliorations basées sur les deux propriétés suivantes du tri par insertion :
- Le tri par insertion est très efficace lorsqu'il opère sur des données presque déjà triées, et peut atteindre l'efficacité d'un tri linéaire.
- Mais le tri par insertion est généralement inefficace, car le tri par insertion ne peut déplacer les données que d'une position à la fois.
Démonstration du processus :

Exemple
#include <stdio.h>
void shell_sort(int arr[], int len);
int main() {
int arr[] = { 22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70 };
int len = sizeof(arr) / sizeof(arr[0]);
shell_sort(arr, len);
for (int i = 0; i < len; i++) {
printf("%d ", arr[i]);
}
return 0;
}
void shell_sort(int arr[], int len) {
for (int gap = len / 2; gap > 0; gap /= 2) {
for (int i = gap; i < len; i++) {
int temp = arr[i];
int j = i;
while (j >= gap && arr[j - gap] > temp) {
arr[j] = arr[j - gap];
j -= gap;
}
arr[j] = temp;
}
}
}
Tri par fusion
Diviser les données en deux segments, puis à partir des deux segments sélectionner un par un le plus petit élément et le déplacer à la fin du nouveau segment de données.
Peut être effectué de haut en bas ou de bas en haut.
Démonstration du processus :


Méthode itérative
#include <stdio.h>
#include <stdlib.h>
int min(int x, int y);
void merge_sort(int arr[], int len);
int main() {
int arr[] = { 22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70 };
int len = sizeof(arr) / sizeof(arr[0]);
merge_sort(arr, len);
for (int i = 0; i < len; i++) {
printf("%d ", arr[i]);
}
return 0;
}
int min(int x, int y) {
return x < y ? x : y;
}
void merge_sort(int arr[], int len) {
int* a = arr;
int* b = (int*) malloc(len * sizeof(int));
if (b == NULL) {
fprintf(stderr, "L'allocation de mémoire a échoué\n");
exit(EXIT_FAILURE);
}
for (int seg = 1; seg < len; seg += seg) {
for (int start = 0; start < len; start += seg + seg) {
int low = start;
int mid = min(start + seg, len);
int high = min(start + seg + seg, len);
int k = low;
int start1 = low, end1 = mid;
int start2 = mid, end2 = high;
while (start1 < end1 && start2 < end2) {
b[k++] = a[start1] < a[start2] ? a[start1++] : a[start2++];
}
while (start1 < end1) {
b[k++] = a[start1++];
}
while (start2 < end2) {
b[k++] = a[start2++];
}
}
int* temp = a;
a = b;
b = temp;
}
if (a != arr) {
for (int i = 0; i < len; i++) {
b[i] = a[i];
}
b = a;
}
free(b);
}
Méthode récursive
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void merge_sort_recursive(int arr[], int reg[], int start, int end);
void merge_sort(int arr[], const int len);
int main() {
int arr[] = { 22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70 };
int len = sizeof(arr) / sizeof(arr[0]);
merge_sort(arr, len);
for (int i = 0; i < len; i++) {
printf("%d ", arr[i]);
}
return 0;
}
void merge_sort_recursive(int arr[], int reg[], int start, int end) {
if (start >= end)
return;
int mid = start + (end - start) / 2;
int start1 = start, end1 = mid;
int start2 = mid + 1, end2 = end;
merge_sort_recursive(arr, reg, start1, end1);
merge_sort_recursive(arr, reg, start2, end2);
int k = start;
while (start1 <= end1 && start2 <= end2) {
reg[k++] = arr[start1] < arr[start2] ? arr[start1++] : arr[start2++];
}
while (start1 <= end1) {
reg[k++] = arr[start1++];
}
while (start2 <= end2) {
reg[k++] = arr[start2++];
}
memcpy(arr + start, reg + start, (end - start + 1) * sizeof(int));
}
void merge_sort(int arr[], const int len) {
int* reg = (int*)malloc(len * sizeof(int));
if (reg == NULL) {
fprintf(stderr, "L'allocation de mémoire a échoué\n");
exit(EXIT_FAILURE);
}
merge_sort_recursive(arr, reg, 0, len - 1);
free(reg);
}
Tri rapide
Choisissez aléatoirement un élément dans l'intervalle comme pivot, placez les éléments plus petits que le pivot avant le pivot, et les éléments plus grands que le pivot après le pivot, puis triez séparément la zone des petits éléments et la zone des grands éléments.
Démonstration du processus :

Méthode itérative
#include <stdio.h>
typedef struct _Range {
int start, end;
} Range;
Range new_Range(int s, int e) {
Range r;
r.start = s;
r.end = e;
return r;
}
void swap(int *x, int *y) {
int t = *x;
*x = *y;
*y = t;
}
void quick_sort(int arr[], const int len) {
if (len <= 0)
return;
Range r[len];
int p = 0;
r[p++] = new_Range(0, len - 1);
while (p > 0) {
Range range = r[--p];
if (range.start >= range.end)
continue;
int mid = arr[(range.start + range.end) / 2];
int left = range.start, right = range.end;
do {
while (arr[left] < mid) ++left;
while (arr[right] > mid) --right;
if (left <= right) {
swap(&arr[left], &arr[right]);
left++;
right--;
}
} while (left <= right);
if (range.start < right) r[p++] = new_Range(range.start, right);
if (range.end > left) r[p++] = new_Range(left, range.end);
}
}
int main() {
int arr[] = {22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70};
int len = sizeof(arr) / sizeof(arr[0]);
quick_sort(arr, len);
for (int i = 0; i < len; i++) {
printf("%d ", arr[i]);
}
return 0;
}
Méthode récursive
#include <stdio.h>
void swap(int *x, int *y) {
int t = *x;
*x = *y;
*y = t;
}
void quick_sort_recursive(int arr[], int start, int end) {
if (start >= end)
return;
int mid = arr[end];
int left = start, right = end - 1;
while (left < right) {
while (left < right && arr[left] < mid)
left++;
while (left < right && arr[right] >= mid)
right--;
swap(&arr[left], &arr[right]);
}
if (arr[left] >= arr[end])
swap(&arr[left], &arr[end]);
else
left++;
quick_sort_recursive(arr, start, left - 1);
quick_sort_recursive(arr, left + 1, end);
}
void quick_sort(int arr[], int len) {
quick_sort_recursive(arr, 0, len - 1);
}
int main() {
int arr[] = {22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70};
int len = sizeof(arr) / sizeof(arr[0]);
quick_sort(arr, len);
for (int i = 0; i < len; i++) {
printf("%d ", arr[i]);
}
return 0;
}
autres extensions