Aller au contenu

Structures de données linéaires - les piles

I. Introduction⚓︎

Il faut se représenter une pile comme... une pile de livres ! Seul le livre disposé sur le dessus est accessible : l'ajout et le retrait d'un livre ne peut donc se faire que sur le sommet de la pile.

LIFO

On dit que les piles sont en mode LIFO (Last In, First Out qui signifie « dernier entré, premier sorti »).

pile LIFO

On ajoute des livres sur la pile, et on les récupère en commençant par le dernier ajouté

Usage courant d'une pile

😊 Les piles sont très utilisées en informatique, en voici quelques usages caractéristiques :

  • Les algorithmes récursifs utilisent une pile d'appel pour mémoriser les contextes d'exécution de chaque appel.
  • La fonction «Annuler la frappe» (en anglais «Undo») d'un traitement de texte mémorise les modifications apportées au texte dans une pile.
  • Comme nous le verrons plus tard dans l'année, on peut aussi utiliser une pile pour parcourir (en profondeur) un graphe et mémoriser les sommets visités.
  • La vérification du bon parenthésage d'une expression peut également se faire à l'aide d'une pile.

Les fonctions primitives pour les PILES sont les suivantes

  • création d'une pile vide (oublié sur l'illustration),
  • tester si une pile est vide,
  • empiler,
  • dépiler.

😊 Et rien de plus ... Pile Gilles

Image crée par Gilles Lassus

Un jeu sérieux

Pour comprendre le principe, vous pouvez jouer à ce jeu :

OCTAVES FLUSH

Représentation possible d'une pile et exemple

🌵🌵 Il n'existe pas une façon "universelle" de représenter les piles. dans cet exemple le sommet sera indiqué avec le symbole > et le fond avec le symbole ]

Une pile contenant les éléments 'a', 'b' et 'c' ('a' étant le sommet et donc 'c' le fond de la pile) sera représentée ici de la façon suivante :

>'a', 'b', 'c']

Exemple : On considère la pile P : >'a', 'b', 'c']. Voici comment la manipuler :

Opération Contenu de la pile
empiler(P, 'e') >'e', 'a', 'b', 'c']
depiler(P) >'a', 'b', 'c']
depiler(P) >'b', 'c']
depiler(P) >'c']
empiler(P, 'm') >'m', 'c']

II. Une implémentation possible des piles⚓︎

Mon info

On donne ci-dessous une possible implémentation de ces fonctions primaires, en utilisant le vocabulaire de la programmation orientée objet que nous avons déjà abordée.

Il existe bien d'autres possibilités pour implémenter ces fonctions primaires.

Dans toute la suite les piles seront affichées entre crochets, comme des list python. Le sommet de la pile est l'élément écrit le plus à droite. Ainsi, si l'on part d'une pile vide, et que l'on empile successivement les entiers 1, puis 2, puis 3, on obtiendra une pile qui s'affichera de la façon suivante : [1, 2, 3]. Le sommet de cette pile est l'entier 3.

La classe Pile

Exécuter absolument le code ci-dessous pour pouvoir continuer.

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Ctrl+Clic pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier

Tester ci-dessous ces primitives

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Ctrl+Clic pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier

Imaginez vos propres tests

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Ctrl+Clic pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier

A vous de jouer

Ecrire ci dessous les instructions qui permettent d'obtenir successivement les affichages suivants :

[12] <- sommet
[12, 14] <- sommet
[12, 14, 8] <- sommet
[12, 14] <- sommet
[12] <- sommet
[] <- sommet

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Ctrl+Clic pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier

Solution
pile_1 = Pile()
pile_1.empiler(12)
print(pile_1)
pile_1.empiler(14)
print(pile_1)
pile_1.empiler(8)
print(pile_1)
pile_1.depiler()
print(pile_1)
pile_1.depiler()
print(pile_1)
pile_1.depiler()
print(pile_1)
La taille d'une pile

Alice désire écrire une fonction, qui doit retourner la taille de la pile.
Attention, une fois que sa taille a été déterminée, la pile ne doit pas avoir été modifiée...
Elle propose le code suivant. L'exécuter absolument

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Ctrl+Clic pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier

Test du code d'Alice

Tester

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Ctrl+Clic pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier

Quel est le problème ?

Pourquoi cette solution ne convient-elle pas ?

Solution

On a bien déterminé la taille de la pile, mais on l'a détruite 😰

Une nouvelle fonction

Ecrire ci-dessous une fonction taille qui remédie à ce problème

Astuce à lire en désespoir de cause ...

Vous pouvez utiliser une deuxième pile ...

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Ctrl+Clic pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier
Évaluations restantes : 5/5

.1280130ldy14k/weibmc:_35aPr+ 7=9of.gt286sSh)(punv050d0k0F0t0l0c0J0x0o0c0t0J0J0z010F0l0O010406050J0P0n0n0t0v0e040K0B0c0P0,0B0Q050i0?0^0`0|0;0O04051c151f0i1c0;0d0l0R0!0$0(0*0L0l0E0L0c1t0L0F0/050V0m0c0k1o0%0)011s1u1w1u0F1C1E1A0F0v1d0F0L0!0 0J0O0t0Q0*0G011G1q010C0X0k0Q0t0n0k1A1Z1#1*1I1-1E1:1=0/0a0x0u0v0B0O0B0J0l120Q0x0T1X0v0v0k0o2a151^0Q1d0i1V2n1S1U1T1B0d1`0*1w0Q1/271A1l1n0#1H2x0l2z0Q0B2D1A0O2g1d2l2n2R0=1!2b2F1+2K0v0_0c0/0f2k2V0:2U1_2X1I2Z2#0/0G2)1#2+2l2w012:0t2$040r2@2m0;2`2.0*2}2 0g322_2V2{380/0s3b343d362|0B2!2~0/0I3i2,2W1p2/3n2;040y3s353v373x3p040H3B3k3D3m3o2 0A3b1g2P152D2q0d1U2v3l0o2L1?1d3U1e3S2T162*053!0T2Q3K2G010h0/0T0C3b0x3t3e0C0/0V0X1E3Q3C3?0.040N453=2Y0/0O1.4b2-3L480M0p3i0x4o3}464d044f1E0q2?3,2^4q4c1I0B0/0z3|3~3l0Q0/0u4g4y2m4H4j0/0N0M4n4p4P3?4J042g0?0c0V0F4G4r4C4E4)4B0*0n0l0/0b4U4o4W1+3^040j1s444N044A4i3?0B0j0/2K4(50523u4X4e4M2T4*0*4D040D4h5c4s0k0J0F0q0R0l0T0q4u0k5m2{484S4m50064p5G5b3e5e4v4x5g4.015j5l504_2/0/0k0n5x0v5z3l5B5!3L4Y5x5%540/5R5N534s0T5Y5+1+5B0M4T5E5H4V5h2|0/4!0P4$0t592R5I3l5j4F5a5T37615p634%4-5:4+040w6j5n1I4:2%4@683L4{4}5f2*6u545604586o5J4t1.4w5@6l5.3-5 4Y5p5r5t5v5*5S5 5_5D2R5F5}6A4s6U5/6p5i5-6K6e045W5?6V5O5$6=6k6.5x6J6^6*5P6,6}6G5=1.5Z715#4R5`6t6d3@6f0F0P0v146c6O6f4#6i5E153/0k2n2O7q3T1m3V2q2t2o0t1D7t0i3U0;7D0U0W0Y04.

III. Vérifier les parenthèses d'une expression mathématique⚓︎

Le but de cet exercice est d'écrire une fonction qui contrôle si une expression mathématique, donnée sous forme d'une chaîne de caractères, est bien parenthésée, c'est-à-dire s'il y a autant de parenthèses ouvrantes que de fermantes. On s'interdit d'utiliser des variables qui "comptent" les parenthèses ouvrantes ou fermantes.

Par exemple

  • (..(..)..) est bien parenthésée.

  • (...(..(..)...) ne l'est pas .

Indication à ne pas dévoiler trop vite ...

On crée une pile. On parcourt l'expression de gauche à droite.
Si on rencontre une parenthèse fermante ")", alors :

  • Si la pile n'est pas vide, on dépile
  • Sinon on renvoie False

À la fin la pile doit être vide...

Implémentation du type Pile

Nous allons utiliser l'implémentation vue au II.
Pour qu'elle soit active, ne pas oublier d'exécuter "la classe Pile"

Les parenthèses

Compléter ci-dessous

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Ctrl+Clic pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier
Évaluations restantes : 5/5

.1280130ldCTy14*-ké/weibmc_:35qaPr+ 7F=9of.gt28;6sSh)(pèuînxv050d0p0M0z0q0c0R0D0t0c0z0R0R0G010M0q0W010406050R0Y0s0s0z0B0g040S0I0c0Y0`0I0!050n111315170 0W04051n1g1q0n1n0 0d0q0$0/0;0?0^0T0q0L0T0c1E0T0M0}050*0r0c0p1z0=0@011D1F1H1F0M1N1P1L0M0B1o0M0T0/1a0R0W0z0!0^0N011R1B010J0,0p0!0z0s0p1L1.1:1^1T1{1P1~200}0a0D0A0B0I0W0I0R0q1d0!0D0(1,0B0B0p0t2l1g230!1o0n1*2y1%1)1(1M0d250^1H0!1}2i1L1w1y0:1S2I0q2K0!0I2O1L0W2r1o2w2y2$101/2m2Q1_2V0B140c0}0D0h2v2*0~2)242,1T2.2:2=0N2^1:2`2w2H012 0z2;040D0w332x0 362}0^393b0D0i3f352*373l2=0x3p3h3r3j380I2/3a2=0Q3w2{2+1A2~3B303c0E3G3i3J3k3L3D3c0O3P3y3R3A3C3m0H3X2|3Z3t040h0b3(3I2R3!3M0h2@1h2_3x3)3;3+0h323_343{3:2-3T3b0h3e413g3H3s460}0h3o4a3q3|453#4f3v4i434d4m3,3F4p4c3z3~3O4v3Q3}4e3,3W4A3Y4C4s0h3%4G4k3K4s0N3.4M444O3M0N3^2$4q4x4D0N404Y4w3*4#494(4B4l4V4h4-4H4/3U0N4o4=4N3S4P4u2(1t2!1g2O2B0d1)2G3z0t2W211o541p52502(5a0(2#4?1T0l0}0(0J3p0D4)3}0J0}0$0p0B0q1{0t0z2u4i5u1_0|040V3p5H2~0}0p0#2Z0u141*5M4.1T5J0U0v3/370o2=0D5*5W5m0^0R0d0}020y0Y0I0M0P5=5@5_5{5^0P5$3z5/5)5*0e0)0M1Q0J1e2t0q1e0D2r0!0$0I0q1Q0f0B0Y1Q2j0D0Y2K0D5Q2Z0p0?6d2m5U0T0m5U0q5?1Q0z0D0z1c1:0M2n0p613Z633c5*0D1/6g1*0X0R6x0D0I0Y0$0B6M6#6G6O6V151}6Y6!0.0J5z140!680R0K6Q3;6S6U2d0B0m5a0!1w2l0D0v6u5R0B5T5E1+6x6N2o0M0g0W1Q0t0T0z0Z6t2o5D6*2t0X2r6}6 1_716U0A2i0M76786z7a0D0;0D0$3a0p0Y0B6f1}6i0g0m1Q7i6.7l7n0D0r0I1a7Y0!6~4S377D5*5Q0p0s0W1P0.5#4p4Z6R5:6T5*020L5}845`867O5z5B0q5D2l0V5~5_0V0w0j0V0N0k0x0#0U0C0w0U8g0P0U7B1T7;0D6m6o8x5.807283858I0P895A5C5E6z8f5?5 8i8k8m8o8q0w8u8w7/628F6U0F3a6!8D018z8H878J8L8b8d8P8u8Z8,8z8B6P7}5N8E640D8_8R5}95604p7290380}0W5s9b0I0}0G9f5X3k0}0A1|5,4|015J0V8!4Y9a9l015o046a0B9k5-9c047v9E9r0I5(042T9J4T9m046v7e6B9q9Q9s0}7|9w726U9b9A5B9P3s0}9I4i5t9y9h040G9j9/9b0R0h5;030w0H0P8f9~a09W375J9!3`9$aa9:9F0!9da53z9=7.2(9yae9S7^1|9D5G9y9tag3*9-15au3;5Z3wabac9r9)5r9_alawaq2$aD9X9=9@9+629|0402a38vaU9 98ak9Fa7aBaC9%9yaFaQav049ear9Faiay2-5P0R0M0u0$0q0(0u0W9pa:9r9t5!a%a(9$9(0}2r0M7S1faH9F0l0t0}8)0-8~9#b7b99Sbla?5Y9Zb6b7a)adafb2aN0}aj2_9bam0(b01PaKbEas0}9ubvbpbbbda,3}bza!9KbCbs9R7ia{a}0pa b1bW9Xb43G0n5j0p2y6w2y5e2z561g2Cb{0z1Ob;531x2`0n0(0*0,0R04.

Source : Stéphan Van Zuijlen