PT – IC STRUCTURE DE PILE
I. Structures de données
1) Généralités
En informatique, il est souvent important de commencer par se poser la question de comment organiser les
données que l’on va exploiter. L’objet informatique général qui permet de stocker des données s’appelle une
structure de donnée, caractérisée par les opérations qu’elle permet, et le coût de ces opérations. D’un point
de vue théorique, les principales sont :
Le tableau : C’est une structure de taille fixe, qui contient un certain nombre d’objets identiques. On accède
à n’importe quel élément en temps constant, mais on ne peut pas insérer ni supprimer d’élément;
La liste (ou liste chaînée) : Dans cette structure, chaque élément se termine par un lien vers l’élément sui-
vant. L’intérêt est que l’insertion ou la suppression d’un élément se fait en temps constant, alors que l’accès
à un élément se fait en O(n) où nest la taille de la liste;
Les ensembles : Ces structures permettent de faire rapidement des opérations comme l’intersection, la réunion
ou le test d’appartenance.
La pile : C’est l’objet du chapitre : on la détaillera plus loin.
En Python, le tableau correspond à un array du module numpy. Par contre, les list de Python sont des objets
qui tiennent à la fois du tableau (on accède directement à n’importe quel élément), de la liste chaînée (les
éléments n’ont pas besoin d’être tous identiques, et on peut changer la taille en temps amorti constant) et,
comme on va le voir, de la pile.
2) La structure de pile
Cette structure correspond exactement à l’idée intuitive que l’on s’en fait : une pile d’assiette (ou de papiers,
ou de cartes...) posée sur une table. En particulier, on ne peut accéder qu’au dernier élément que l’on a empilé,
qu’on appelle le sommet de la pile. ↑↓
C
B
A
Par exemple, si on empile successivement A, puis B, puis C, on obtient la situation ci-contre. On a
alors le choix entre deux opérations : empiler un quatrième objet D ou dépiler C. Si on veut accéder à
l’élément A, il faut commencer par dépiler C, puis B.
Ce type de structure de donnée est fondamental en informatique. Au niveau du langage machine, il sert à
gérer les appels à une fonction et le passage de paramètre. Plus proche de l’utilisateur, on le retrouve dans
tous les contextes ou on a un bouton « annuler » ou « revenir à la page précédente ».
On résume souvent le comportement d’une pile sous la forme « dernier arrivé, premier sorti » ou en anglais
« Last In, First Out » que l’on résume par l’acronyme LIFO. Il existe aussi une structure de file d’attente où le
premier arrivé est le premier sorti (First In, First Out ou FIFO). On parle dans ce cas de structure de file, mais
ce n’est pas directement au programme. On rencontre ces structures par exemple dans les serveurs d’impres-
sion d’une imprimante réseau, on dans un parcours d’arbre en largeur (mais là encore on sort du cadre du
programme).
II. Opérations sur une pile
Une pile est caractérisée par quatre opérations qui doivent prendre un temps constant (autrement dit avoir
une complexité en O(1)), indépendamment de la taille de la pile :
creerPile() : renvoie une nouvelle pile vide;
empiler(p, x) : empile x sur la pile p;
depiler(p) : dépile et renvoie le sommet de la pile p;
estVide(p) : indique si la pile p est vide.
1/4 DELAY – Paul Constans
PT – IC STRUCTURE DE PILE
D’autre fonction sont souvent utiles, même si elles ne sont pas totalement indispensables :
taille(p) : renvoie le nombre d’éléments de la pile p;
sommet(p) : renvoie le sommet de la pile p.
Exercice 1 : Écrire les fonctions précédentes. On simulera la pile par une list python.
Remarque : Le fait d’implémenter une pile par une liste python permettrait d’autres opérations que celles
citées plus haut (par exemple accéder directement à n’importe quel élément). Dans toutes la suite, on s’inter-
dira d’accéder à une pile autrement qu’avec ces fonctions (sans quoi on ne travaille plus sur des piles!) En TP,
on commencera les scripts en important ces fonctions que l’on mettra dans une bibliothèque pile.py
Exercice 2 :
1. Écrire une fonction copierPile(p) qui prend en argument une pile pet renvoie une copie de psans modi-
fier p. Évaluer la complexité en espace (c’est à dire le coût en mémoire) et le nombre d’opérations effectuées
par cette fonction.
2. Écrire une fonction inverserPile(p) qui prend en argument une pile pet retourne une autre pile dont
les éléments sont ceux de p, mais dans l’ordre inverse. pne doit pas être modifiée.
III. Applications
Les questions marquées (*) sont plus difficiles, ou moins fondamentales, et peuvent être gardées pour la fin.
1) Analyse des mots bien parenthésés
Vous avez remarqué que sous la plupart des EDI, l’ajout de parenthèse fermante surnuméraire est signalé,
et que les paires de parenthèses correspondantes sont surlignés. L’objectif de cette section est d’écrire un
programme qui vérifie si une chaîne de caractères ne contenant que des parenthèses est bien parenthésée. Par
exemple, ’()(())’ est correct, mais ’)(’ ne l’est pas. On se propose de plus d’indiquer, pour chaque parenthèse
ouvrante, la position de la parenthèse fermante correspondante. Par exemple, pour ’()(())’, on indiquera les
couples (0,1), (2,5) et (3,4).
L’idée de l’algorithme est de parcourir la chaîne de gauche à droite. Pour chaque caractère :
si c’est une parenthèse ouvrante, empiler son indice;
si c’est une parenthèse fermante, deux cas possibles :
si la pile est vide, c’est que cette parenthèse ne correspond à aucune parenthèse ouvrante est donc la
chaîne est mal parenthésée;
sinon, on dépile l’indice de la parenthèse ouvrante correspondante, et on affiche le couple d’indices.
Arrivé à la fin de la chaîne de caractères, la chaîne est bien parenthésée à condition que la pile soit vide.
Exercice 3 :
1. Écrire la fonction bienParenthese(s) correspondant à l’algorithme ci-dessus.
2. Adapter la fonction précédente pour qu’elle accepte des chaînes de caractères comprenant des paren-
thèses et d’autres caractères n’influant pas sur le résultat. Par exemple ’(2+3)-(4*(5-2)+1)’ est bien paren-
thésée, mais pas ’(5+1)*7)’.
3. (*) Adapter la fonction précédente pour qu’elle traite les mots constitués de plusieurs couples de symboles
ouvrant ou fermant (’(’, ’)’ ou ’[’, ’]’ ou ’{’, ’}’). Un mot est alors bien parenthésé si le symbole fermant cor-
respond au symbole ouvrant. Par exemple ’{()}[]’ est bien parenthésée, mais pas ’{(})’.
2/4 DELAY – Paul Constans
PT – IC STRUCTURE DE PILE
2) Notation polonaise inversée
La notation polonaise inversée (NPI) est utilisée sur certaines calculatrices (pour plus de détails, voir http:
//fr.wikipedia.org/wiki/Notation_polonaise_inverse). Dans cette notation, les opérateurs arithmé-
tique (+, ,×, ...) sont placés après leurs opérandes (on parle de notation post-fixée). Par exemple, 2+3 s’écrit
2 3 + et 2+3×4 devient 2 3 4 * +. L’un des avantages de cette notation est qu’elle rend inutile l’utilisation
de parenthèses. Par exemple, l’expression (2+4)×3, on pourrait s’écrire 2 4 + 3 *.
L’évaluation d’une expression en NPI nécessite une pile. Le principe est le suivant : le texte est lu de gauche à
droite. Pour chaque élément,
si c’est un nombre, on l’empile;
si c’est un opérateur, on dépile les deux derniers nombres, on effectue le calcul, et on empile le résultat.
Le résultat est alors au sommet de la pile.
Exercice 4 : On se propose d’écrire un programme qui demande à l’utilisateur une expression en NPI et qui
affiche sa valeur. On pourra se contenter de travailler dans Net ne gérer que les opérateurs +et ×.
1. Traduire l’algorithme informellement donné ci dessus. Dans cette question, on ne demande pas le détail
des fonctions utilisées, mais seulement leur spécification (reconnaître un opérateur, effectuer l’opération
correspondante, ...). On pourra considérer que l’expression est donnée sous forme d’une liste, par exemple
[10,11,’+’,2,’*’].
2. Implémenter effectivement les fonctions utilisées.
3. (*) Écrire une fonction qui demande à l’utilisateur de taper une expression en NPI, et qui renvoie la liste cor-
respondante. Par exemple, si l’utilisateur tape 10 11 + 2 *, la fonction renvoie [10,11,’+’,2,’*’].
On pourra utiliser la méthode split sur la chaîne de caractères entrée par l’utilisateur.
4. (*) Ajouter les opérations de soustraction et de division entière à votre fonction.
5. (*) Ajouter des opérateurs unaires (par exemple calculant le carré, l’opposé, la valeur absolue, . . .).
3) (*) Création de labyrinthe
La structure de pile permet aussi de construire simplement un labyrinthe dans lequel il y a un unique trajet
permettant d’aller d’une case à une autre (donc en particulier un unique trajet de l’entrée à la sortie). Le
principe est le suivant :
On marque la case de départ comme atteinte et on l’empile;
Tant que la pile n’est pas vide :
On dépile une case;
Si elle a des voisines non explorées :
on en choisit une au hasard comme case d’arrivée;
on ouvre un couloir entre les deux cases;
on marque la case d’arrivée comme visitée;
on empile les deux cases.
Exercice 5 :
1. Quelle structure de donnée permet de mémoriser les cases visitées? L’implémenter et écrire des fonctions
est_visitee(x, y) qui indique si la case de cordonnées (x, y) est déjà visitée et visiter(x, y) qui
marque la case comme visitée. On pourra utiliser des variables globales HAUT et LARG pour les dimensions
du labyrinthe.
2. Écrire une fonction voisines(x, y) qui renvoie la liste des voisines non visitées d’une case.
3. Écrire une fonction couloir(x0, y0, x1, y1) qui trace un couloir entre deux cases.
4. Écrire le programme correspondant à l’algorithme ci-dessus.
3/4 DELAY – Paul Constans
PT – IC STRUCTURE DE PILE
Fonctions utiles :
La fonction choice du module random
La fonction fill du module matplotlib.pyplot
On peut obtenir quelque chose comme ceci avec par exemple l’entrée en bas à gauche et la sortie en haut à
droite :
4/4 DELAY – Paul Constans
1 / 4 100%
La catégorie de ce document est-elle correcte?
Merci pour votre participation!

Faire une suggestion

Avez-vous trouvé des erreurs dans linterface ou les textes ? Ou savez-vous comment améliorer linterface utilisateur de StudyLib ? Nhésitez pas à envoyer vos suggestions. Cest très important pour nous !