Exercice: Tri par sélection#
Les fonctions de manipulation de liste chaînée que nous avons développées nous permettent maintenant d’implémenter le tri par sélection sur les listes comme vu en cours.
liste *tri_selection(liste *l);
Les principales étapes du tri sont les suivantes :
Créer une nouvelle liste
r
qui va recevoir les éléments triés.Tant que la liste d’origine
l
n’est pas vide faire :Chercher le maximum
m
de la listel
.Supprimer la valeur
m
de la listel
.Ajouter la valeur
m
en tête de la lister
.
Libérer la liste
l
Retourner la liste
r
Afin de vérifier que notre implémentation est correcte, nous allons vérifier deux des invariants de cet algorithme à la fin de chaque itération:
la somme des longueurs des deux listes est constante ;
la liste
r
est une liste triée.
Écrire une fonction
est_triee
qui prend en paramètre une liste et renvoie un booléen indiquant si la liste est bien triée dans l’ordre croissant.BEGIN SOLUTION
bool est_triee(liste *l) { if (l->nbelem <= 1) return true; int v = l->tete->val; elem *e = l->tete->next; while (e != NULL) { if (e->val < v) return false; v = e->val; e = e->next; } return true; }
END SOLUTION
Écrire maintenant la fonction de tri par sélection sur les listes en vérifiant bien que les invariants sont vérifiés à la fin de chaque itération.
BEGIN SOLUTION
liste *tri_selection(liste *l) { int k = l->nbelem; liste *r = nouvelle_liste(); while (l->nbelem != 0) { int max = chercher_maximum(l); supprimer_valeur(l, max); ajouter_en_tete(r, max); // vérification des invariants if (l->nbelem + r->nbelem != k) { cout << "|l| + |r| invalide" << endl; } if (esttriee(r) == false) { cout << "r n'est pas triée" << endl; } } liberer_liste(l); return r; }
END SOLUTION