Structures de données linéaires



Documents pareils
Centre CPGE TSI - Safi 2010/2011. Algorithmique et programmation :

TP n 2 Concepts de la programmation Objets Master 1 mention IL, semestre 2 Le type Abstrait Pile

Les structures de données. Rajae El Ouazzani

Génie Logiciel avec Ada. 4 février 2013

Algorithmique, Structures de données et langage C

PROBLEMES D'ORDONNANCEMENT AVEC RESSOURCES

Université Bordeaux 1, Licence Semestre 3 - Algorithmes et struct...

Chapitre 5 : Flot maximal dans un graphe

6. Hachage. Accès aux données d'une table avec un temps constant Utilisation d'une fonction pour le calcul d'adresses

Systemes d'exploitation des ordinateurs

Initiation à la Programmation en Logique avec SISCtus Prolog

UEO11 COURS/TD 1. nombres entiers et réels codés en mémoire centrale. Caractères alphabétiques et caractères spéciaux.

SYSTÈME DE GESTION DE FICHIERS

Chapitre V : La gestion de la mémoire. Hiérarchie de mémoires Objectifs Méthodes d'allocation Simulation de mémoire virtuelle Le mapping

Structure fonctionnelle d un SGBD

Le chiffre est le signe, le nombre est la valeur.

Conventions d écriture et outils de mise au point

Déroulement. Evaluation. Préambule. Définition. Définition. Algorithmes et structures de données 28/09/2009

DU BINAIRE AU MICROPROCESSEUR - D ANGELIS CIRCUITS CONFIGURABLES NOTION DE PROGRAMMATION

Cours d initiation à la programmation en C++ Johann Cuenin

Compression de Données - Algorithme de Huffman Document de Conception

REALISATION d'un. ORDONNANCEUR à ECHEANCES


Travaux pratiques. Compression en codage de Huffman Organisation d un projet de programmation

SYSTÈME DE GESTION DE FICHIERS SGF - DISQUE

Exercices types Algorithmique et simulation numérique Oral Mathématiques et algorithmique Banque PT

Définitions. Numéro à préciser. (Durée : )

LibreOffice Calc : introduction aux tableaux croisés dynamiques

Quelques Algorithmes simples

ARBRES BINAIRES DE RECHERCHE

Info0101 Intro. à l'algorithmique et à la programmation. Cours 3. Le langage Java

Architecture des ordinateurs TD1 - Portes logiques et premiers circuits

Factorisation Factoriser en utilisant un facteur commun Fiche méthode

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP

INF601 : Algorithme et Structure de données

1. Introduction Création d'une macro autonome Exécuter la macro pas à pas Modifier une macro... 5

Initiation. àl algorithmique et à la programmation. en C

Recherche dans un tableau

Cours 1 : Introduction Ordinateurs - Langages de haut niveau - Application

C++ COURS N 2 : CLASSES, DONNÉES ET FONCTIONS MEMBRES Classes et objets en C++ Membres d'une classe Spécification d'une classe Codage du comportement

Architecture des Systèmes d Information Architecture des Systèmes d Information

Algorithme. Table des matières

Projet d informatique M1BI : Compression et décompression de texte. 1 Généralités sur la compression/décompression de texte

Les opérations binaires

Pour signifier qu'une classe fille hérite d'une classe mère, on utilise le mot clé extends class fille extends mère

EXCEL TUTORIEL 2012/2013

Algorithmique et Programmation

Représentation d un entier en base b

2 Grad Info Soir Langage C++ Juin Projet BANQUE

Chap 4: Analyse syntaxique. Prof. M.D. RAHMANI Compilation SMI- S5 2013/14 1

Cours 1 : Introduction. Langages objets. but du module. contrôle des connaissances. Pourquoi Java? présentation du module. Présentation de Java

Université Ibn Zohr Excel Résume de cours

Conception de circuits numériques et architecture des ordinateurs

Bases de programmation. Cours 5. Structurer les données

MISE A NIVEAU INFORMATIQUE LANGAGE C - EXEMPLES DE PROGRAMMES. Université Paris Dauphine IUP Génie Mathématique et Informatique 2 ème année

Représentation des Nombres

IN Cours 1. 1 Informatique, calculateurs. 2 Un premier programme en C

Seconde Généralités sur les fonctions Exercices. Notion de fonction.

SOMMAIRE. Travailler avec les requêtes... 3

Cours d introduction à l informatique. Partie 2 : Comment écrire un algorithme? Qu est-ce qu une variable? Expressions et instructions

chapitre 4 Nombres de Catalan

Rappels sur les suites - Algorithme

Arbres binaires de recherche

L exclusion mutuelle distribuée

# let rec concat l1 l2 = match l1 with [] -> l2 x::l 1 -> x::(concat l 1 l2);; val concat : a list -> a list -> a list = <fun>

Programmation Objet - Cours II

GESTION DE STOCKS AVEC CIEL GESTION COMMERCIALE

MICROINFORMATIQUE NOTE D APPLICATION 1 (REV. 2011) ARITHMETIQUE EN ASSEMBLEUR ET EN C

Les arbres binaires de recherche

Débuter avec Excel. Excel

IV- Comment fonctionne un ordinateur?

SUPPORT DE COURS. Dr. Omari Mohammed Maître de Conférences Classe A Université d Adrar Courriel : omarinmt@gmail.com

Cours A7 : Temps Réel

GESTION DE LA MEMOIRE

Les algorithmes de base du graphisme

Introduction à la programmation orientée objet, illustrée par le langage C++ Patrick Cégielski

MODE D'EMPLOI DE LA CALCULATRICE POUR LES COURTS SÉJOURS DANS L'ESPACE SCHENGEN

I. Introduction aux fonctions : les fonctions standards

Cours 02 : Problème général de la programmation linéaire

Fiche des fonctions du téléphone Business Communications Manager

Partie 7 : Gestion de la mémoire

données en connaissance et en actions?

1 è r e étape : créer sa base de d o n n é e s

Prénom : Matricule : Sigle et titre du cours Groupe Trimestre INF1101 Algorithmes et structures de données Tous H2004. Loc Jeudi 29/4/2004

Introduction à MATLAB R

Probabilités. I Petits rappels sur le vocabulaire des ensembles 2 I.1 Définitions... 2 I.2 Propriétés... 2

Ensimag 1ère année Algorithmique 1 Examen 2ième session 24 juin Algorithmique 1

Chapitre 2. Eléments pour comprendre un énoncé

1. Introduction Création d'une requête...2

Algorithmique avec Algobox

Architecture des ordinateurs

1 de 46. Algorithmique. Trouver et Trier. Florent Hivert. Mél : Florent.Hivert@lri.fr Page personnelle : hivert

CHAPITRE VIII : Les circuits avec résistances ohmiques

Initiation à la programmation en Python

Synthèse d'images I. Venceslas BIRI IGM Université de Marne La

Techniques de stockage. Techniques de stockage, P. Rigaux p.1/43

Edition de sites Jahia 6.6

1. Création d'un état Création d'un état Instantané Colonnes Création d'un état Instantané Tableau... 4

1. Utilisation du logiciel Keepass

Transcription:

Structures de données linéaires I. Liste, Pile et file. Une liste linéaire est la forme la plus simple et la plus courante d'organisation des données. On l'utilise pour stocker des données qui doivent être traitées de manière séquentielle. Exemple On désire, pour les besoins de la programmation d'un jeu de cartes, représenter le paquet de cartes. Parmi toutes les informations que l'on possède sur les cartes, la plupart sont inutiles (couleur du dos, taille, matière, propriétaire ). Seuls nous intéressent, la couleur (trèfle, carreau, coeur ou pique), la hauteur (valeur de la carte), et le coté visible de la carte. Pour chacune des cartes ces informations utiles seront codées et rangées dans un article. Ainsi on effectuera le codage suivant: - pour le coté visible: Face = 1 signifie que la carte est "cachée" (dos visible) Face = 0 signifie que la carte est "visible" (face visible) - pour la couleur: couleur = 1 pour trèfle couleur = 2 pour carreau couleur = 3 pour coeur couleur = 4 pour pique - pour la hauteur: hauteur = 1 pour l'as hauteur = 2 pour le deux hauteur = 12 pour la dame hauteur = 13 pour le roi Un article aura alors la forme suivante : De plus, on pourra éventuellement adjoindre à cet article une zone "suivant" servant à indiquer l'adresse de l'élément suivant. Ainsi on aura la représentation de l'article sous la forme : page 1

Le paquet de quatre cartes suivant : pourra alors être représenté par : Définition Une liste linéaire est une suite finie (éventuellement vide) d'articles de même type X[1], X[2],, X[N] avec N>0, dont la propriété est qu'il est linéaire (une dimension), ordonné et : si N>0 alors X[1] est le premier article si 1<k<N alors X[k] est précédé de X[k-1] et est suivi de X[k+1]. Les articles sont repérés selon leur rang dans la liste mais il ne faut pas confondre le rang et la position! Les opérations que l'on peut désirer réaliser sur une telle structure sont entre autres : - examiner le kième élément de la liste - insérer un élément avant le kième élément de la liste - supprimer le kième élément de la liste - réunir deux listes - rechercher les articles dont une zone contient une certaine valeur - etc Il existe différents type de listes linéaires. Un exemple tiré de la vie courante peut être le rangement de vêtements et son organisation comportemental. Dans certains types de listes les opérations d'insertion et de suppression se déroulent toujours aux extrémités de la liste. Ces types de listes se rencontrant très fréquemment, on leur a donné un nom. Définition Une Pile est une structure de données linéaire dans laquelle les opérations d'insertion et de suppression se font à une extrémité appelée sommet. L'autre extrémité étant désignée par le terme "fond de pile". On rencontre également le terme LIFO (Last In First Out) pour désigner ce type de structure. Exemples - pile d'assiettes - pile d'un microprocesseur - une pile est utilisée pour le calcul des expressions postfixées page 2

Représentations Définition Une File est une structure de données linéaire dans laquelle les opérations d'insertion se font à une extrémité appelée arrière et les opérations de suppression se font à l'autre extrémité appelée front. On rencontre également le terme FIFO (Fist In Fist Out) pour désigner ce type de structure. Exemples - file de voitures - de manière générale : Les files d'attentes Représentations Définition Une queue ou double file (ou deque) est une structure de données linéaire dans laquelle les opérations d'insertion et de suppression se font aux deux extrémités. Représentation Remarque On distingue également les Queues à entrée restreinte (QER) dans lesquelles on ne peut insérer qu'à une extrémité, mais sortir aux deux extrémités; et les Queues à sortie restreinte (QSR) dans lesquelles on ne peut supprimer qu'à une extrémité, mais insérer à l'une des deux extrémités. page 3

II. Implantation en mémoire Nous représenterons la mémoire comme une série de cases numérotées de 1 à M. M étant le nombre de cases mémoires disponible permettant le stockage des informations. Ainsi, les articles X[ i ] sont rangés dans ces cases. L'emplacement, l'adresse d'un article X[ i ] est alors le numéro de la case où il débute. 1. La Méthode séquentielle C'est la façon la plus naturelle de procéder. En effet les articles X[ i ] de la liste linéaire sont rangés, les uns à la suite des autres, dans des cases mémoires consécutives. Ainsi, si chaque article a besoin de C cases mémoires pour son stockage, on aura: Adresse de X[ j + 1 ] = Adresse de X[ j ] + C = A1 + j * C (où A1 est l'adresse de X[ 1 ]). On peut donc, sans difficulté, accéder à un article quelconque de la liste linéaire, en connaissant l'adresse de base A1. Par la suite nous supposerons, pour plus de commodité, que C = 1 et A1 = 1. Etudions, à présent les cas particuliers de la pile et de la file. a. Cas d'une pile Les opérations d'insertion et de suppression se font à une extrémité (sommet). Il faut donc connaître en permanence l'adresse de celle-ci. Pour cela, on utilisera un pointeur T qui nous indiquera où se trouve le sommet. Primitives Les opérations de base sur les piles sont simples : empiler(p,e) : empile l'élément e dans la pile p. dépiler(p) : dépile un élément de la pile p et renvoie cette valeur. page 4

Les opérations d'insertion et de suppression pourrons alors se réaliser avec les instructions suivantes : Insertion de Y T = T + 1; X [ T ] = Y; Suppression Y = X [ T ]; T = T - 1; Mais ici se pose deux problèmes: - vouloir supprimer un élément alors que la pile est vide - vouloir insérer un élément alors que la pile est pleine (les M cases mémoires réservées à la pile sont occupées). Il va donc falloir gérer ces exceptions et on écrira alors: Insertion de Y si (T == M) alors PLEIN(); { T = T + 1; X [ T ] = Y; Suppression si (T == 0) alors VIDE(); { Y = X [ T ]; T = T - 1; Où VIDE() et PLEIN() simulent les exceptions (appel à une procédure d'erreur, sortie du traitement, etc). b. Cas d'une file Les opérations d'insertion se font à une extrémité (arrière) et les opérations de suppression se font à l'autre extrémité (front). Il faut donc connaître en permanence l'adresse de celles-ci. Pour cela, on utilisera un pointeur F qui nous indiquera où se trouve le front et un pointeur A qui nous indiquera où se trouve l'arrière. Les opérations d'insertion et de suppression pourrons alors se réaliser avec les instructions suivantes : Insertion de Y A = A + 1; X [ A ] = Y; Suppression Y = X [ F ]; F = F + 1; A nouveau ici se pose deux problèmes: - vouloir supprimer un élément alors que la file est vide - vouloir insérer un élément alors que la file est pleine (les M cases mémoires réservées à la file sont occupées). page 5

De plus, le fait que les deux pointeurs soient incrémentés lors de chaque opération signifie que l'on risque de se retrouver dans le cas où le début de mémoire est inoccupé, le pointeur A étant en fin de mémoire (A = M) et interdire ainsi les opérations d'insertions. Pour ne pas interrompre le traitement, dans un tel cas de figure, on va supposer la mémoire comme étant circulaire. La file X pourra alors prendre la forme suivante: Il reste encore un problème à résoudre. En effet, dans une telle configuration, les tests de file vide et de file pleine sont identiques (A = F - 1). Pour pouvoir différencier les deux cas, on va supposer que la case pointée par F est "interdite" pour le stockage d'un élément de la file. Les opérations d'insertion et de suppression pourront alors se réaliser avec les instructions suivantes: Insertion de Y si ((A == F-1) ou (A == M et F == 1)) PLEIN(); { si (A == M) alors A = 1; A = A + 1; X [A] = Y; Suppression si (A == F) alors VIDE(); { si (F == M) alors F = 1; F = F + 1; Y = X [F]; Le problème de la différentiation entre une liste pleine et une liste vide aurait pu aussi se résoudre en ajoutant une variable booléenne qui passerai de vrai à faux dès la première insertion d un élément. page 6

Remarquons aussi que l on peut à tout moment connaître le nombre d éléments de la file : - Si A > F, il s agit de A - F. - Si A <= F, il s agit de M - F + A. 2. Les listes «chaînées» Une autre approche traditionnelle pour implanter une liste est l utilisation de pointeurs. De cette façon, la mémoire est allouée dynamiquement : la réservation de l espace se fait en fonction des données insérées ou supprimées. a. Listes simplement chaînées On ajoute à chaque article un information complémentaire qui pointe vers l article suivant. L ensemble sera appelé un maillon ou un noeud. On peut représenter ce type de liste de la façon suivante : Noeud Tête de liste Fin de liste La tête de liste est une variable qui va «pointer» le premier élément de la liste. Chaque article (noeud) est composer de son information et d un pointeur vers le noeud suivant. Le dernier article n ayant pas de suivant pointe vers vide, nil ou null représenté dans l exemple suivant par /. La linéarité de cette représentation est purement virtuelle. En effet, les éléments n'ont aucune raison d'être ordonnés ou contigus en mémoire. Chaque élément est lié à son successeur. Il n'est donc pas possible d'accéder directement à un élément quelconque de la liste. On peut simuler ce type de liste dans un tableau : Début de liste rang 0 1 2 3 valeur 4 7 12 25 suivant 1 / 3 0 Fin de chaînage Mais en utilisant un tableau, on perd évidemment le côté dynamique de l allocation de la mémoire. page 7

Primitives tetedeliste(lst) : permet d accéder au pointeur désignant la tête de liste de la liste lst. valeur(p,lst) ou plus simplement valeur(p): permet d accéder à la valeur du noeud pointé par p de la liste lst. suivant(p,lst)ou plus simplement suivant(p): permet d accéder au suivant du noeud pointé par p de la liste lst. Si on s intéresse un peu plus à l allocation mémoire, on peut aussi considérer des fonctions qui initialise une liste, crée un noeud pointé par p ou libère l espace mémoire d un noeud pointé par p. Insertion d un élément dans une liste chaînée Il y a trois cas différents que nous devons traiter : l insertion en début de liste, au sein de la liste et en fin de liste. Insertion en début de liste : p = creernoeud(); // Ces deux lignes sont inutiles valeur(p) = information; // si le noeud existe déjà. suivant(p) = tetedeliste(lst); tetedeliste(lst) = p; Remarquons que cette suite d instructions convient pour une insertion dans une liste vide. Insertion après un noeud pointé par q : p = creernoeud(); valeur(p) = information; suivant(p) = suivant(q); suivant(q)= p; Insertion en fin de liste : Il faut en premier lieu parcourir toute la liste et ensuite insérer après le dernier élément de celle-ci. p = creernoeud(); valeur(p) = information; si (tetedeliste(lst) == NIL) { suivant(p) = NIL; tetedeliste(lst) = p; { q = tetedeliste(lst); tant que (suivant(q)!= NIL) { q = suivant(q); suivant(p) = NIL; suivant(q)= p; Suppression d un élément dans une liste chaînée Nous nous intéressons à la suppression du noeud pointé par p dans une liste lst. Le problème consiste à retrouver le prédécesseur de p. page 8

Exercice si (tetedeliste(lst) == p) tetedeliste(lst) = suivant(p); { tant que (suivant(q)!= p) q = suivant(q); suivant(q) = suivant(p); Trouver un algorithme qui donne le nombre d éléments d une liste chaînée lst. Correction Exercice si (tetedeliste(lst) == NIL) nbr = 0; { q = tetedeliste(lst); nbr = 1; tant que (suivant(q)!= NIL) { nbr = nbr + 1; q = suivant(q); Trouver un algorithme donnant le maximum des valeurs d une liste chaînée non vide d entiers lst. Correction q = tetedeliste(lst); max = valeur(q); tant que (suivant(q)!= NIL) { q = suivant(q); si (valeur(q) > max) max = valeur(q); Exercices supplémentaires a. Ecrire une fonction qui indique si une valeur fait partie d une liste. b. Ecrire une fonction qui renvoie la n-ième valeur d'une liste (traiter les cas où il n y a pas de n-iéme élément. c. Ecrire une fonction qui concatène deux listes lst1 et lst2. d. Ecrire une fonction qui renverse une liste lst pour obtenir une liste lstinverse. e. Ecrire une fonction qui insère un élément p dans une liste lst (non vide) triée par ordre croissant. f. Ecrire une fonction qui fusionne deux listes non vides lst1 et lst2 triées pour obtenir de nouveau une liste triée lst. page 9

b. Listes doublement chaînées Le parcours d une liste chaînée se fait en sens unique. Cela complique bien des problèmes. Une solution apportée à ce parcours et de faire appel à une liste doublement chaînée. Ce type de liste est similaire à une liste chaînée à ceci près que l on adjoint à chaque noeud une information qui est l adresse de son prédécesseur. Exemple De nouveau, cette linéarité est purement virtuelle. Tout comme pour la liste chaînée, les noeuds ne sont pas nécessairement adjacents et/ou ordonnés en mémoire. Primitives En plus des primitives des listes simplement chaînées, c est-à-dire : tetedeliste(lst), valeur(p)et suivant(p), nous avons : findeliste(lst)qui permet d accéder au pointeur désignant la fin de liste de la liste lst. precedent(p)qui permet d accéder au précèdent du noeud pointé par p. Insertion d un élément dans une liste doublement chaînée De même que pour les listes simplement chaînées, il y a trois cas différents que nous devons traiter : l insertion en début de liste, au sein de la liste et en fin de liste. On gérera en même temps les exceptions. Insertion en début de liste : p = creernoeud(); // Ces deux lignes sont inutiles valeur(p) = information; // si le noeud existe déjà. si tetedeliste(lst) == NIL) { findeliste(lst) = p; suivant(p) = NIL; /* idem a */ precedent(p) = NIL; /* idem b */ tetedeliste(lst) = p; /* idem c */ { precedent(tetedeliste(lst)) = p; suivant(p) = tetedeliste(lst); /* idem a */ precedent(p) = NIL; /* idem b */ tetedeliste(lst) = p; /* idem c */ page 10

Remarquons que les lignes /* idem a */, /* idem b */ et /* idem c */ des deux cas effectuent les même opérations et peuvent donc être exclues du test et placées en fin d instructions. Insertion en fin de liste : p = creernoeud(); valeur(p) = information; si (findeliste(lst) == NIL) debutdeliste = p; suivant(findeliste(lst)) = p; precedent(p) = findeliste(lst); suivant(p) = NIL; findeliste(lst) = p; Insertion après un noeud pointé par q : si (q == findeliste(lst)) { insérer en fin de liste { p = creernoeud(); valeur(p) = information; suivant(p) = suivant(q); precedent(p) = q; precedent(suivant(q)) = p; suivant(q)= p; Suppression d un élément dans une liste doublement chaînée si (tetedeliste(lst) == p) { si (findeliste(lst) == p) { tetedeliste(lst) = NIL; findeliste(lst) = NIL; { tetedeliste(lst) = suivant(p); precedent(suivant(p)) = NIL; si (findeliste(lst) == p) { findeliste(lst) = precedent(p); suivant(precedent(p)) = NIL; { suivant(precedent(p)) = suivant(p); precedent(suivant(p)) = precedent(p); Exercice Ecrire une fonction qui insère un noeud p dans une liste lst (non vide) triée par ordre croissant. page 11

Correction si (valeur(p) < valeur(tetedeliste(lst)) insérer p en début de liste; { q = tetedeliste(lst); tant que (valeur(p) < valeur(q)) q = suivant(q); si (q!= NIL) insérer p après le precedent de q; insérer p à la fin de la liste; Exercice Ecrire une fonction qui fusionne deux listes non vides lst1 et lst2 triées pour obtenir de nouveau une liste triée lst. Remarque 1: on n'utilisera pas la fonction de l exercice précédent. Remarque 2 : c est évidement beaucoup plus simple en récursif en considérant qu une liste est un premier élément et une liste. Correction p = tetedeliste(lst1); q = tetedeliste(lst2); tetedeliste(lst) = NIL; tant que ((p!=nil) && (q!=nil)) { si ((p!=nil) && (q!=nil)) si (valeur(p) < valeur(q)) { insérer le noeud p à la fin de la liste lst p = suivant(p); { insérer le noeud q à la fin de la liste lst q = suivant(q); si (p==nil) { insérer le noeud q à la fin de la liste lst q = suivant(q); { insérer le noeud p à la fin de la liste lst p = suivant(p); c. Listes circulaires Une liste circulaire peut être simplement chaînée ou doublement chaînée. Elle s obtient en remplaçant le ou les pointeurs NIL par le pointeur de tête de liste et, dans le cas d une liste doublement chaînée par le pointeur de début de liste. On obtient une liste qui n a ni premier ni dernier élément. Tous les noeuds sont accessibles à partir de n importe quel autre. page 12

III. Un exemple d'utilisation de pile : expressions arithmétiques Les piles ont de nombreuses applications : les navigateurs web (précédent), les annulateurs d actions dans un traitement de texte ou autres logiciels, les algorithmes de recherches en profondeur d un arbre ou implicitement les algorithmes récursifs de certains langages. Une des applications des piles nécessite de s y attarder un peu. Il s agit des expressions arithmétiques et de la méthode postfixée de calcul qui est utilisée par exemple dans certaines calculatrices HP. Les expressions arithmétiques sont habituellement écrites de manière infixée, c'est à dire qu un opérateur binaire est placé entre ses deux opérandes. Mais une autre façon d évaluer les expressions mathématiques consiste à placer l'opérateur après ses opérandes. C est ce qu on appelle la notation postfixée, appelée aussi notation polonaise inversée car introduite en 1920 par le polonais Jan Lukasiewicz : Cela permet d éviter les parenthèses et pas conséquent d optimiser le compilateur. Exemple 3 + 4 s'écrit en postfixé : 3 4 + 3 + 5-9 s'écrit en postfixé : 3 5 + 9 - Un intérêt de cette notation est qu'il n'y a plus besoin de connaître les priorités des opérateurs, et donc plus besoin de parenthèses (qui servent à contrer les priorités). 3 + 2 * 5 c est-à-dire 3 + (2 * 5) s'écrit en postfixé : 3 2 5 * + (3 + 2) * 5 s'écrit en postfixé : 3 2 + 5 * 4 + 7 * (8 + 2) s'écrit en postfixé : 4 7 8 2 + * + 4 7 + 8 2 * + donne en infixé : 4 + 7 + 8 * 2 Pour effectuer un calcul en postfixé, on utilise une pile. On lit de gauche à droite et les règles sont les suivantes : Si on rencontre : - un nombre : on l'empile - un opérateur binaire: on dépile le sommet et le sous sommet on effectue le calcul sous-sommet "opération" sommet on empile le résultat - un opérateur unaire (une fonction ou le moins unaire) : on dépile le sommet on calcule la fonction pour la valeur du sommet on empile le résultat Remarque : Il faut bien différencier le moins unaire de l opérande de soustraction. Pour cela, on utilisera plutôt NEG ou +/- pour l opérateur unaire. Un autre avantage du calcul en postfixé dans une calculatrice est qu il n y a pas d état caché. L utilisateur n a pas besoin de se demander s il a bien frappé la touche + - * ou / d une calculatrice. En effet, une frappe entraîne immédiatement un calcul. D un autre côté, il ne faut pas malencontreusement frapper deux fois une touche d opération. page 13

Exercice Avec l'expression ci-dessous donnez les modifications de la pile en respectant les règles (en supposant la pile vide au départ) 2 5 + 4 5 3 + 2 ^ * * Quelle est l écriture courant (infixée) de cette expression? Correction Il s agit de (2 + 5)% 4%(5 + 3) 2. Traducteur L inconvénient le plus important du calcul en postfixé consiste en la gymnastique intellectuelle de traduction d infixé en postfixé qui croît en complexité avec la taille de l expression à traduire. Un question naturel devient donc : y-a-t-il un algorithme pour passer d'une infixe à une postfixe? La réponse est oui : la méthode consiste à empiler les opérateurs. On lit l'expression infixée caractère par caractère. Si c'est un opérande, on l'écrit. Sinon (c'est un opérateur), si la pile est vide ou bien si l'opérateur est (strictement) plus prioritaire que l'opérateur en sommet de pile, alors on l'empile. Sinon, on dépile jusqu'à pouvoir l'empiler. Lorsqu il n y a plus d opérandes, on dépile. Remarque x y est un opérateur binaire. Il s agit de x ^ y. Exemples 2 + 3 * 4-5 + 6 devient 2 3 4 * + 5-6 + 3 + 2-5 * 6 / 2 + 3 devient 3 2 + 5 6 * 2 / - 3 + Pour les parenthèses : on doit empiler les ouvrantes. Quant aux fermantes, elles imposent de tout dépiler jusqu'à l'ouvrante associée. Exemple 2 * 3 + 5 * (1 + 6 * 4) + 7 devient 2 3 * 5 1 6 4 * + * + 7 + 2 * ( 5 + 4 * (3 + 2 ) ^ 2 ) devient 2 5 4 3 2 + 2 ^ * + * Remarque Ne pas oublier qu il y a parfois des parenthèses sous-entendues. page 14

Exemple 3 + 5%4 + (1 + 2) 2 = (3 + 5%4) + ((1 + 2) 2 ) et devient donc 3 5 4 * + 1 2 + 2 ^ + Exercice Traduire en postfixé l expression 3& 4 + 5 2 + 2 + 1/6&7. Correction 3 4 5 2 ^ 2 + + * 1 6 / 7 * + page 15