Algo_E1 : Piles & Files à l aide de tableaux 1.1 Exercice 1 : Pile (LIFO : «last in, first out») On désire réaliser la notion de pile à l'aide d'une structure de données définie comme suit : enreg Tpile Tobj Elts[MAX] entier NbElts Le type Tpile est un enregistrement comportant 2 champs : Elts : tableau devant contenir les éléments de la pile. La capacité de la pile est définie par MAX. Le type des éléments est Tobj. NbElts : nombre d éléments dans la pile. On supposera que les éléments de la pile sont rangés dans l ordre des indices croissants. Pour une pile vide, NbElts doit être égal à zéro. 1.1.a) Proposez un jeu d'algorithmes pour les opérations suivantes : procédure initialiser (résultat Tpile pile) procédure empiler (résultat Tpile pile, valeur Tobj E) procédure depiler (résultat Tpile pile, résultat Tobj E) fonction pilevide (valeur Tpile pile) retour entier fonction pilepleine (valeur Tpile pile) retour entier Pour chacun des algorithmes donnés, on indiquera leur complexité en fonction du nombre d'éléments dans la pile. On rappelle que dans une pile, le dernier élément ajouté doit être le premier à sortir. 1.1.b) Ecrire un algorithme vérifiant l existence d un élément de valeur e dans la pile dont les éléments sont mémorisés triés. Ce traitement devra être basé sur une recherche dichotomique de l indice de l élément du tableau contenant la valeur e (la recherche pouvant ne pas aboutir si un tel élément n existe pas). Le principe d une telle recherche sur un tableau T de N éléments numérotés de 1 à N est le suivant : - on accède à l élément i = N / 2 (division entière de N par 2) ; - si T[i] = e, on a gagné ; - si T[i] < e, on itère la recherche aux éléments (i + 1).. N du tableau ; - enfin, si T[i] > e, on itère le processus de recherche aux éléments 1.. (i - 1) ; - on arrête les itérations lorsque l intervalle de recherche est réduit à 1 élément. Donner la complexité de cet algorithme. Exos_Algo_06/07 --- Page 1
1.2 Exercice 2 : File (FIFO : «first in, first out») On veut maintenant réaliser la notion de file à l'aide de la structure de données définie ci-après : enreg Tfile Tobj Elts[MAX] entier id entier NbElts Les 3 champs du type Tfile ont la signification suivante : Elts : tableau devant contenir les éléments de la file ; la capacité de la file est définie par MAX. Id : indice de l élément le plus ancien dans la file si NbElts est non nul. La file est gérée comme un buffer circulaire ; le contenu de la file est défini par les indices compris entre Id et (Id+Nbelts) mod MAX (a mod b désignant le reste de la division entière de a par b). Nbelts : nombre d éléments dans la file (0 pour une file vide). Proposez un jeu d'algorithmes pour les opérations suivantes : procédure initialiser (résultat Tfile file) procédure ajouter (résultat Tfile file, valeur Tobj E) procédure retirer (résultat Tfile file, résultat Tobj E) fonction filevide (valeur Tfile file) retour entier fonction filepleine (valeur Tfile file) retour entier Pour chacun des algorithmes donnés, on indiquera leur complexité en fonction du nombre d'éléments dans la file. On rappelle que dans une file, le premier élément ajouté doit être le premier à en sortir. 1.3 Exercice 3 : File d attente avec priorité Dans cet exercice, on suppose que tout élément est muni d'une priorité représentée par un entier qui doit être précisé au moment de l'ajout de l'élément dans la file. La procédure de retrait doit maintenant chercher l'élément le plus prioritaire. On s'intéresse à une implémentation efficace des opérations. La file d'attente sera définie par 2 structures de données : Telt et TfilePrio enreg Telt entier priorite Tobj obj Chaque élément de la file d'attente est décrit par un enregistrement de type Telt comportant 2 champs : priorite : entier représentant la priorité de l'élément obj : une valeur d'un type Tobj non précisé décrivant l'élément Exos_Algo_06/07 --- Page 2
enreg TfilePrio Telt elts[max] entier nbelts Donnez une implémentation des fonctions ajouter et retirer dans les 2 cas suivants : 1. On décide pour la procédure ajouter de ranger les éléments dans un ordre quelconque. Ce qui implique que la procédure retirer doit parcourir la liste pour extraire l'élément prioritaire, puis tasser le tableau pour qu'il n'y ait pas de trous. 2. On décide dans la procédure ajouter de maintenir les éléments par ordre de priorité croissante. Les procédures ajouter et retirer sont déclarées comme suit : procédure ajouter (résultat TfilePrio file, valeur entier prio, valeur Tobj obj) procédure retirer (résultat TfilePrio file, résultat Tobj obj) Quelle est la complexité des algorithmes obtenus dans les 2 cas? 1.4 Arbres binaires équilibrés n1 racine n2 n3 n4 père n5 n6 n7 n8 n9 n10 fils n11 n12 n13 Figure 1 : notion d'arbre Un arbre est constitué d un ensemble d'éléments appelés nœuds reliés entre eux par une relation binaire. Un nœud particulier porte le nom de racine. Tout nœud autre que la racine est relié à un autre nœud appelé père. On dit aussi que le premier nœud est un fils du second. Un arbre généalogique est un exemple parfait d'arbre : un nœud peut avoir plusieurs fils, mais ne peut avoir qu'un seul père. Les nœuds qui n'ont pas de fils sont appelés les feuilles de l'arbre. Exos_Algo_06/07 --- Page 3
Le degré d'un nœud est le nombre de fils qu'il possède. La profondeur d'un nœud est la longueur du chemin qui le sépare de la racine. On dit qu'un arbre est équilibré si les profondeurs des feuilles ne diffèrent pas de plus de 1. Un arbre binaire est un arbre dans lequel tout nœud a au plus 2 fils. Une manière d implémenter un arbre binaire équilibré à l'aide d'un tableau est de procéder comme suit : la racine est placée en position 0 un noeud en position i a son fils gauche en position 2*i+1, et son fils droit en position 2*i+2 Parcourir le tableau dans l'ordre croissant des indices revient à parcourir l'arbre de la racine vers les feuilles en largeur d'abord : c'est à dire qu'on parcourt tous les nœuds d'un niveau avant de passer au niveau suivant. Exemple : 58(0) 20(1) 35(2) 11(3) 15(4) 23(5) 19(6) 7(7) 9(8) 11(10) 6(9) 16(11) 3(12) 2(13) 17(14) indices file 0 1 2 3 4 5 6 7 8 9 10 11 13 14 12 58 20 35 11 15 23 19 07 09 06 11 16 03 02 17 Figure 1 : Exemple d'arbre binaire vérifiant la propriété de tas Propriété d un tas : Supposons que chaque nœud de l'arbre soit muni d'une priorité (entier positif). On dira qu un arbre binaire vérifie la propriété de tas si la priorité d'un nœud est toujours supérieure à celle de ses fils. C est à dire : Pour i compris entre 0 et (Nb/2) 1 on a : priorite(i) >= priorite(2*i+1) et priorite(i) >= priorite(2*i+2) Exos_Algo_06/07 --- Page 4
En particulier, la racine possède la plus grande priorité parmi tous les nœuds de l'arbre... Exercice : application à la file d'attente avec priorité On utilise les structures de données définies dans l'exercice 1.3 (file d attente avec priorité). On décide de considérer les éléments du tableau comme les nœuds d'un arbre équilibré vérifiant la propriété de tas. Ajouter un élément à la suite du tableau revient à ajouter une feuille à l'arbre, mais alors la propriété de tas n'est plus nécessairement vérifiée : il faut alors échanger la position du nœud avec celle de son père s il y a violation de la propriété de tas. Le processus doit être répété avec le père jusqu'à ce qu'il n'y ait plus violation, ou jusqu'à la racine. Retirer un élément revient à en extraire la racine, puisque l'arbre vérifie la propriété de tas. Mais alors on n a plus de racine. On remplacera la racine par le dernier élément du tableau (qui est une feuille). Ce remplacement détruit la propriété de tas. Il faut alors tester si la nouvelle racine a une priorité moindre que le maximum des priorités de ses fils, et faire l'échange si c'est le cas. Lorsqu un tel échange est réalisé, le processus doit être répété jusqu'à ce qu'il n'y ait plus violation, ou jusqu'à ce qu'on ait atteint les feuilles de l'arbre. Proposer un algorithme pour les procédures ajouter et retirer correspondantes. Quelle est la complexité des algorithmes ainsi proposés dans le pire des cas? Exos_Algo_06/07 --- Page 5
Algo_E2 : Piles & Files à l aide de listes chaînées 2.1 Exercice 1 : Pile (LIFO) On désire réaliser la notion de pile à l'aide des 2 structures de données définies ci-après. enreg Telmt Tobj obj Telmt *suiv Le type Telmt est un enregistrement comportant 2 champs : obj : contient un objet de type Tobj ; suiv : pointeur sur l élément suivant de la liste. et enreg Tpile Telmt *premier Le type Tpile est un enregistrement comportant 1 seul champ : premier : pointeur sur le premier élément de la pile. Il doit être nul si la pile est vide. Proposez un jeu d'algorithmes pour les opérations suivantes : procédure initialiser (résultat Tpile pile) procédure empiler (résultat Tpile pile, valeur Tobj E) procédure depiler (résultat Tpile pile, résultat Tobj E) fonction pilevide (valeur Tpile pile) retour booléen fonction pilepleine (valeur Tpile pile) retour booléen Pour chacun des algorithmes donnés, on indiquera leur complexité en fonction du nombre d'éléments dans la pile. On rappelle que dans une pile, le dernier élément ajouté doit être le premier à sortir. 2.2 Exercice 2 : File (FIFO) On désire réaliser la notion de file à l'aide de la structure de données définie ci-dessous : enreg Tfile Telmt *premier Telmt *dernier Exos_Algo_06/07 --- Page 6
Les 2 champs du type Tfile ont pour signification : premier : pointeur sur le premier élément de la file. Il doit être nul si la file est vide ; dernier : pointeur sur le dernier élément de la file. Il doit être nul si la file est vide. Proposez un jeu d algorithmes pour les opérations suivantes : procédure initialiser (résultat Tfile file) procédure ajouter (résultat Tfile file, valeur Tobj E) procédure retirer (résultat Tfile file, résultat Tobj E) fonction filevide (valeur Tfile file) retour booleen Pour chacun des algorithmes donnés, on indiquera leur complexité en fonction du nombre d'éléments dans la file. On rappelle que dans une file, le premier élément ajouté doit être le premier à sortir. 2.3 Exercice 3 : polynôme creux Dans cet exercice, on se propose de développer un module permettant de manipuler des polynômes creux. Un polynôme creux est un polynôme contenant très peu de monômes non nuls. Exemple : P(x) = 5.6 x 1280 + 0.8 x 9 contient 1281 termes dont 3 seulement sont non nuls. enreg Tmonome entier deg réel coef Tmonome *suiv P 1280 5.6 1 0.8 0-9 Chaque monôme est décrit par un enregistrement de type Tmonome comportant les 3 champs suivants : deg : entier représentant le degré du monôme ; coef : réel représentant le coefficient du monôme ; suiv : pointeur sur le monôme suivant. enreg Tpolynome Tmonome *prem Un polynôme sera décrit par une structure Tpolynome contenant un seul champ prem : Si prem est nul, le polynôme correspondant sera le polynôme zéro ; Si prem est non nul, il pointera sur le monôme de plus haut degré dont le coefficient est non nul. Les monômes de coefficient non nuls sont chaînés par ordre de degré décroissant. Proposez un algorithme pour la procédure ajouter : procédure ajouter (résultat Tpolynome pol, valeur entier deg, valeur réel coef) qui ajoute à un polynôme (pol) la valeur d un monôme défini par son degré (deg) et son coefficient (coef). Exos_Algo_06/07 --- Page 7
On s intéresse maintenant à l implémentation des opérations additionner et multiplier dont les déclarations sont données ci-dessous. Ces opérations construisent le polynôme résultat somme (respectivement produit) de deux polynômes : procédure additionner (valeur Tpolynome1 pol1, valeur Tpolynome1 pol2, résultat Tpolynome1 pol3) procédure multiplier (valeur Tpolynome1 pol1, valeur Tpolynome1 pol2, résultat Tpolynome1 pol3) Proposez des algorithmes pour les opérations additionner et multiplier utilisant la procédure ajouter de la question précédente. Quelle est la complexité des algorithmes obtenus en fonction du nombre de monômes non nuls des 2 polynômes opérandes? Proposez un autre algorithme pour l opération additionner sans utiliser la procédure ajouter, en remarquant que chaque fois que l on ajoute un monôme au polynôme résultat, il est toujours placé à la fin puisque les monômes sont rangés dans un ordre décroissant. Quelle est la complexité de l algorithme obtenu? Proposez une solution pour réduire le temps de calcul du produit de 2 polynômes. Exos_Algo_06/07 --- Page 8
Algo_E3 : Récursivité 3.1 Exercice 1 : Chaîne de caractères Proposez un algorithme récursif qui permette de saisir une chaîne de caractères terminée par le caractère., puis d afficher cette chaîne de façon inversée (le tout devant être réalisé via une seule procédure). On se servira pour cela uniquement des opérations suivantes : fonction lire_caractere () retour caractère procédure afficher_caractere (valeur caractère c) 3.2 Exercice 2 : Tri Quick-Sort Donner une version complète de l algorithme de tri rapide dont le principe est exposé dans le support de cours d. Exos_Algo_06/07 --- Page 9
Algo_E4 : Exercice récapitulatif : Tri par fusion On s'intéresse au tri de données (des nombres réels) gérées sous forme de file d attente, c est à dire que les ajouts à la file se font en queue et les retraits en tête. On supposera défini le type Tfile dont on ne connaît pas les détails. Mais on dispose des opérations suivantes pour manipuler des objets de type Tfile : procédure Créer (résultat Tfile file) : crée une file nouvelle ; la file créée persiste jusqu'à ce qu'elle soit détruite. procédure Détruire (résultat Tfile file) : détruit une file existante. procédure Initialiser (résultat Tfile file) : applicable sur une file déjà existante ; cette procédure a pour effet de vider le contenu de la file. procédure Ajouter (résultat Tfile file, valeur réel E) : ajoute la valeur E en queue de file. procédure Retirer (résultat Tfile file, résultat réel E) : retire l'élément en tête de file et le place dans E. fonction FileVide (valeur Tfile file) retour booléen : retourne vrai si la file est vide et faux sinon. fonction PremierElement (valeur Tfile file) retour réel : retourne la valeur du premier élément si la file est non vide ; cette fonction ne modifie pas le contenu de la file!!! On peut toujours considérer une file de réels comme constituée de séquences monotones. Une séquence monotone est une séquence triée dans l'ordre croissant. Deux éléments successifs de la file appartiennent à une même monotonie si le premier est plus petit ou égal au second. Lorsqu'une file est triée, elle est constituée d'une seule monotonie. Lorsqu'elle n'est pas triée, elle est constituée de plusieurs monotonies. Exemple La file 7 4 10 13 9 50 23 67 17 est composée de 5 monotonies repérées par des barres : 7 4 10 13 9 50 23 67 17 4.1 procédure Eclater 4.1.1 procédure TransfertMonotonie Proposez un algorithme pour la procédure TransfertMonotonie procédure TransfertMonotonie (résultat TFile Lsource, résultat TFile Ldestination) qui retire la monotonie en tête de la file Lsource et la place en queue de la file Ldestination. On supposera que Lsource n'est pas vide et que Ldestination est une file valide (initialisée correctement) et non nécessairement vide. Exos_Algo_06/07 --- Page 10
Exemple si Lsource correspond à la file : 4 10 13 9 50 23 67 17 et Ldestination à : 7 après exécution de TransfertMonotonie on a Lsource : 9 50 23 67 17 et Ldestination : 7 4 10 13 4.1.2 procédure Eclater Proposez un algorithme pour la procédure Eclater procédure Eclater ( résultat TFile Lsource, résultat TFile Ldest1, résultat TFile Ldest2, résultat entier nb_monotonies) qui crée deux files Ldest1, Ldest2 à partir d'une file Lsource. Cette procédure devra initialiser les files Ldest1 et Ldest2 puis utiliser la procédure TransfertMonotonie pour répartir les monotonies de la file initiale entre Ldest1 et Ldest2. Le paramètre nb_monotonies sera utilisé pour indiquer le nombre de monotonies de la file initiale. Exemple : si initialement on a Lsource: 7 4 10 13 9 50 23 67 17 - Ldest1:??? - Ldest2:??? - nb_monotonies:??? après invocation de Eclater (Lsource, Ldest1, Ldest2, nb_momotonies), on doit avoir la situation suivante : Lsource: vide - Ldest1: 7 9 50 17 - Ldest2: 4 10 13 23 67 - nb_monotonies : 5 4.2 Procédure fusionner 4.2.1 Procédure FusionMonotonie Donnez un algorithme pour la procédure FusionMonotonie procédure FusionMonotonie (résultat TFile Lsource1, résultat TFile Lsource2, résultat TFile Ldestination) qui retire des files Lsource1 et Lsource2 les monotonies en tête de file, et les fusionne en une monotonie unique placée en queue de la file Ldestination. On supposera que les files Lsource1 et Lsource2 ne sont pas vides, et contiennent donc chacune au moins une monotonie. La file Ldestination sera supposée déjà initialisée et non nécessairement vide. Exemple : à partir de Lsource1: 9 50 17 - Lsource2: 4 10 13 3 67 - Ldestination: 7 on a, après FusionMonotonie (Lsource1, Lsource2, Ldestination), la situation suivante : Lsource1: 17 - Lsource2: 3 67 - Ldestination: 7 4 9 10 13 50 Exos_Algo_06/07 --- Page 11
4.2.2 Procédure Fusionner Utiliser le sous-programme précédent pour exprimer l algorithme de la procédure Fusionner qui fusionne les monotonies de deux files Lsource1 et Lsource2 en une troisième file Ldestination. Ldestination devra être initialisée avant le début de la fusion. procédure Fusionner (résultat TFile Lsource1, résultat TFile Lsource2 résultat TFile Ldestination) Quelle est la complexité de l algorithme Fusionner? 4.3 Procédure Tri_Par_Fusion Utiliser les procédures Eclater et Fusionner pour déduire un algorithme de tri par fusion en observant que, après éclatement et fusion, la file obtenue possède un nombre de monotonies divisé par 2. procédure Tri_Par_Fusion (résultat TFile File) Donnez la complexité de l'algorithme développé en fonction du nombre d'éléments dans la file. /* Applications à venir */ 4.4 Application 1 : tri de listes chaînées Proposez une implémentation du type Tfile ainsi que des opérations de manipulation des files qui permettent de trier des listes chaînées. 4.5 Application 2 : tri de tableaux Proposez une implémentation du type Tfile ainsi que des opérations de manipulation des files qui permettent de trier un tableau pouvant contenir (au plus) N réels. 4.6 Application 3 : tri de fichiers Proposez une implémentation du type Tfile ainsi que des opérations de manipulation des files permettant de trier un fichier. Exos_Algo_06/07 --- Page 12