U. A. G. - UFR S.E.N 2006-2007 Proposition de Correction TP3 PEROUMALNAÏK M. mail: [email protected] web : http://grimaag.univ-ag.fr/~mperouma/ Après avoir corrigé en cours le sujet original, nous allons, au cours de ce document, réaliser cette même correction mais en utilisant des fonctions à la fois pour : – 1) la saisie – 2) l'affichage – 3) le tri (par sélection puis à bulle) I] Exercice 1 : 1] Enoncé Ecrire un programme permettant de lire et de ranger dans l'ordre croissant un ensemble d'entiers tapés au clavier selon la méthode du tri par sélection : Ce tri consiste à rechercher le plus petit élément d'un tableau de n éléments et à relever son indice i dans [0..n[ dans le tableau. A la fin du premier tour de boucle, cette valeur devra se trouver à l'indice 0 du tableau. On devra donc permuter les valeurs d'indices i et 0 et il ne reste plus ensuite qu'à trier le tableau sur les éléments restant [1..n[. On répète alors la procédure jusqu'à ce que tous les (n – 1) éléments du tableau aient été traités. 2] Proposition de correction Ce tri fonctionne simplement : il s'agit, par comparaisons successive de ranger progressivement le tableau en éléments de taille croissante et par ordre de parcours : ainsi, à la fin du tri, l'élément le plus petit se retrouve en début de tableau et le plus grand à la fin. Le tri s'effectuant progressivement, on choisit de ne pas reparcourir les cases déjà triés, ce qui veut dire qu'au premier tour de tri, les comparaisons vont se faire sur les cases du tableau d'indices compris entre [0, N-1] (pour une taille de Avril 2007 – LS1 UE012 – PEROUMALNAÏK M. U. A. G. - UFR S.E.N 2006-2007 tableau égale à N), au second tour, entre [1, N-1], ainsi de suite, jusqu'au dernier tour, entre [N-2, N-1]. Donc, au final, pour ce tri, nous aurons à considérer deux boucles de traitement imbriquées : – la première qui fera évoluer une variable i (par exemple) sur [0 N-2] pour ranger chacune des cases du tableau, – la seconde, interne, qui fera évoluer une variable j (idem) sur [i N-1] pour déterminer quel est l'indice de la case de valeur minimale sur l'ensemble des cases non triées. Une des difficultés que vous avez rencontrées est au niveau du début du tri : en effet, comment trouver la valeur minimale du tableau et comment l'initialiser ? Selon moi, la façon la plus judicieuse de le faire est de commencer la comparaison en prenant comme valeur de départ, qui nous servira de base de comparaison, la première case non triée du tableau. Fixons les idées avec un exemple, pour N = 3 : le tableau [ 8 | 9 | 0 ]. Nous utiliserons la variable i pour la boucle externe, la variable j pour la boucle interne, min pour mémoriser la valeur de l'indice de la case contenant l'élément le plus petit. Etape Tableau i j min 1 [8|9|0] 0 0 0 2 [8|9|0] 0 1 0 3 [8|9|0] 0 2 2 4 [0|9|8] 1 1 1 5 [0|9|8] 1 2 2 On remarque bien qu'ici, à la fin de la boucle de comparaison, il faut permuter le plus petit élément avec la première case non-triée du tableau. Classiquement, cette permutation s'effectue à l'aide d'une troisième variable, qui sert de tampon. Nous pouvons donc passer à l'algorithme pour ce tri, en nous rappellant qu'ici, nous nous préparons à écrire notre programme en utilisant des fonctions. Avril 2007 – LS1 UE012 – PEROUMALNAÏK M. U. A. G. - UFR S.E.N 2006-2007 a) Algorithme Tout d'abord, la procédure qui nous intéresse le plus : celle qui permet de trier le tableau: PROCEDURE : Tri_selection(tab, N) PARAMETRES : tab : tableau[1,N] d'entiers N : entier VARIABLES : i,j,min,temp : entier DEBUT Pour i allant de 1 à N­1 Faire min <­ i Pour j allant de i à N Faire Si tab[j] < tab[min] alors min <­ j FinSi FinPour temp <­ tab[min] tab[min] <­ tab[i] tab[i] <­ temp FinPour FIN Ensuite, deux procédures annexes, faciles : une qui permet de saisir le tableau, l'autre qui permet de l'afficher PROCEDURE : lire_tab(tab, N) PARAMETRES : tab : tableau[1,N] d'entiers N : entier VARIABLES : i : entier DEBUT Pour i allant de 1 à N Faire Avril 2007 – LS1 UE012 – PEROUMALNAÏK M. U. A. G. - UFR S.E.N 2006-2007 ecrire('Saisir la case',i,'du tableau') lire(tab[i]) FinPour FIN PROCEDURE : afficher_tab(tab, N) PARAMETRES : tab : tableau[1,N] d'entiers N : entier VARIABLES : i : entier DEBUT ecrire('[ ') Pour i allant de 1 à N­1 Faire ecrire(tab[i],' | ') FinPour ecrire(tab[N],' ]') FIN b) Code Regardez attentivement la structure du code ainsi que les entêtes des fonctions. Voir le fichier TP3_exo1.c => (http://grimaag.univ-ag.fr/~mperouma/telechargements/TP3_exo1.c ) Avril 2007 – LS1 UE012 – PEROUMALNAÏK M. U. A. G. - UFR S.E.N 2006-2007 II] Exercice 2 : 1] Enoncé Reprendre le même exercice que précédemment avec la méthode du tri à bulle. Méthode : Le tri à bulle consiste à parcourir le tableau de N éléments de gauche à droite en comparant chaque élément à son prédécesseur et à les permuter si le premier des deux éléments est supérieur au second. L'algorithme est le suivant : Les deux premiers éléments sont comparés. Si le premier est supérieur au second, on les permute. Les comparaisons continuent ensuite ainsi : indices 1 et 2, puis 2 et 3 ... et enfin N-2 et N-1. Ainsi l'élément le plus grand se trouve, par permutations successives, placé en dernière position dans le tableau. Reste ensuite à recommencer la méthode pour le reste du tableau : indices 0 à N-2, et ainsi de suite. L'algorithme se termine lorsqu'aucune permutation n'est possible. 2] Proposition de correction Ce tri permet, par comparaison successives de deux voisins, de ranger le tableau en ordre croissant Après avoir lu l'algorithme, pour ce tri, nous aurons à considérer deux boucles de traitement imbriquée : – la première qui fera évoluer les permutations, tant qu'il reste des éléments à permuter, en évitant de parcourir les cases déjà rangées – la seconde, interne, qui fera évoluer une variable j (idem) sur [0 N-1] pour changer de place deux cases voisines n'étant pas en ordre croissant. Pour cet algorithme, vous m'avez présenté plusieurs solutions, dont une qui boucle tant qu'il reste des tris à faire. Je n'ai pas retiré de points, mais le tri, bien que fonctionnant, est incomplet. Voyons l'algorithme : Avril 2007 – LS1 UE012 – PEROUMALNAÏK M. U. A. G. - UFR S.E.N 2006-2007 a) Algorithme Dans cette procédure, nous allons utiliser une boucle tant-que avec deux indicateurs : – un premier permettant d'éviter de retrier les cases déjà rangées – un second permettant d'arrêter le tri si il n'y a pas eu de permutation au tour précédent Toujours dans une logique de « fonctions » on a donc : PROCEDURE : Tri_bulle(tab, N) PARAMETRES : tab : tableau[1,N] d'entiers N : entier VARIABLES : i,j,temp,test : entier DEBUT i <­ N­1 test <­ 1 Tant que ((i > 1) ET (test > 0) Faire test <­ 0 Pour j allant de 1 à i Faire Si tab[j] < tab[j+1] alors temp <­ tab[j] tab[j] <­ tab[j+1] tab[j+1] <­ temp test <­ test + 1 FinSi FinPour i <­ i­1 FinTantQue FIN b) Code Voir le fichier TP3_exo2.c => (http://grimaag.univ-ag.fr/~mperouma/telechargements/TP3_exo2.c ) Avril 2007 – LS1 UE012 – PEROUMALNAÏK M.