Implémentation avec tableau circulaire
Le cadre
On propose ici, en Python, une implémentation qui utilise en arrière-plan une structure de type list de Python, mais en limitant volontairement l'usage, comme un tableau, sans méthode dynamique. Ainsi l'implémentation pourrait être réalisée dans de nombreux langages de programmation avec de rares ajustements.
On montre ci-dessous des exemples d'une file modélisée par un tableau circulaire :
[_, _, _, _, _, _, _]: une file vide à 7 éléments au maximum[1, 2, 3, 4, _, _, _]: une file avec 4 éléments enfilés[_, _, 3, 4, _, _, _]: on a défilé 2 éléments[8, _, 3, 4, 5, 6, 7]: on a enfilé 4 éléments[8, _, _, _, _, 6, 7]: on a défilé 3 éléments[_, _, _, _, _, _, _]: on a défilé 3 éléments ; la file est vide
Deux/trois variables utiles
On peut maintenir deux variables qui indiquent :
i: l'indice où enfiler le prochain élémentj: l'indice où défiler le prochain élément
Schématisons les 4 dernières étapes de l'exemple précédent
On va défiler le 6 à l'indice 6, il restera alors 2 éléments.
(Si on voulait enfiler, ce serait à l'indice 1)
graph TB
classDef Nil stroke:none,fill:none,color:none;
A["8"]
B["None"]
C["None"]
D["None"]
E["None"]
F["None"]
G["6"]
H["7"]
eA[" "]:::Nil ~~~ A
eB@{ shape: braces, label: "i = 1" } --> B
eC[" "]:::Nil ~~~ C
eD[" "]:::Nil ~~~ D
eE[" "]:::Nil ~~~ E
eF[" "]:::Nil ~~~ F
eG@{ shape: braces, label: "j = 6" } --> G
eH[" "]:::Nil ~~~ H
T@{ shape: braces, label: "taille = 3" }
On va défiler le 7 à l'indice 7, il restera alors 1 élément.
(Si on voulait enfiler, ce serait à l'indice 1)
graph TB
classDef Nil stroke:none,fill:none,color:none;
A["8"]
B["None"]
C["None"]
D["None"]
E["None"]
F["None"]
G["None"]
H["7"]
eA[" "]:::Nil ~~~ A
eB@{ shape: braces, label: "i = 1" } --> B
eC[" "]:::Nil ~~~ C
eD[" "]:::Nil ~~~ D
eE[" "]:::Nil ~~~ E
eF[" "]:::Nil ~~~ F
eG[" "]:::Nil ~~~ G
eH@{ shape: braces, label: "j = 7" } --> H
T@{ shape: braces, label: "taille = 2" }
On va défiler le 8 à l'indice 0, il restera alors aucun élément.
(Si on voulait enfiler, ce serait à l'indice 1)
graph TB
classDef Nil stroke:none,fill:none,color:none;
A["8"]
B["None"]
C["None"]
D["None"]
E["None"]
F["None"]
G["None"]
H["None"]
eA@{ shape: braces, label: "j = 0" } --> A
eB@{ shape: braces, label: "i = 1" } --> B
eC[" "]:::Nil ~~~ C
eD[" "]:::Nil ~~~ D
eE[" "]:::Nil ~~~ E
eF[" "]:::Nil ~~~ F
eG[" "]:::Nil ~~~ G
eH[" "]:::Nil ~~~ H
T@{ shape: braces, label: "taille = 1" }
La file est vide ; prête pour enfiler à l'indice 1.
graph TB
classDef Nil stroke:none,fill:none,color:none;
A["None"]
B["None"]
C["None"]
D["None"]
E["None"]
F["None"]
G["None"]
H["None"]
eA[" "]:::Nil ~~~ A
eB@{ shape: braces, label: "i = j = 1" } --> B
eC[" "]:::Nil ~~~ C
eD[" "]:::Nil ~~~ D
eE[" "]:::Nil ~~~ E
eF[" "]:::Nil ~~~ F
eG[" "]:::Nil ~~~ G
eH[" "]:::Nil ~~~ H
T@{ shape: braces, label: "taille = 0" }
Une autre variable est utile, la taille qui permet de savoir si la pile est vide ou pleine, car dans les deux cas, on a i == j.
Il y aurait une autre possibilité, ce serait interdire de remplir la dernière case libre... Dans ce cas, il faut initialiser un tableau avec une case de plus.
Exercice
On donne le début d'une classe File :
class File():
"""Classe File avec tableaux Python"""
def __init__(self, taille_max: int):
self.taille_max = taille_max
self.données = [None] * taille_max # un tableau
self.i = 0 # l'indice où on va enfiler un élément
self.j = 0 # l'indice d'où on va défiler un élément
self.taille = 0
Compléter la classe File (est_vide, enfile et défile) :
- L'initialiseur prend
taille_maxen paramètre, et crée une file vide.- qui s'appuie sur un tableau de
données, initialement rempli deNone.
- qui s'appuie sur un tableau de
- On peut enfiler jusqu'à atteindre la
taille_max, - mais tenter d'enfiler un élément de plus provoquera
raise ValueError("File pleine !") - Si on défile, on remplacera la donnée dans le tableau par
None. - Tenter de défiler alors que la file est vide provoquera
raise ValueError("File vide !") - L'attribut
self.iindique :- l'indice du tableau où on va enfiler le prochain élément,
- L'attribut
self.jindique :- l'indice du tableau où on va défiler le prochain élément,
- L'attribut
self.tailleindique la taille réelle de la file.
# Tests(insensible à la casse)(Ctrl+I)
(Alt+: ; Ctrl pour inverser les colonnes)
(Esc)