3. USEK
Faculté
d'Ingénierie
GIN231 - 201120
Les Files - Définition
• Le premier élément inséré dans une file est donc le
premier élément sorti : Nous disons que la file a un
comportement FIFO : First In First Out. Par ailleurs, la
valeur d'une file est par convention celle de l'élément
de tête.
• Le comportement FIFO permet de modéliser et de
gérer des ensembles d'objets qui sont en attente d'un
traitement ultérieur, en particulier les files d'attente.
– Par exemple, la file d’attente à un guichet de cinéma : Les
gens entrent dans la file à la queue et ils sortent de la file
dès qu’ils sont en tête.
4. USEK
Faculté
d'Ingénierie
GIN231 - 201120
Les Files - Définition
• Une file est une structure de données linéaire pour
laquelle les insertions d’éléments se font toutes d’un
même côté, appelé queue de file, et les suppressions se
font de l’autre côté, appelé tête de file.
En anglais, une
file se dit queue.
6 3 5 2 7 1 4Enfilement Défilement
Tête de fileQueue de file
5. USEK
Faculté
d'Ingénierie
GIN231 - 201120
Opérations sur les files
• Les opérations de base sur les files sont au nombre de cinq.
– Créer une file vide. Queue()
– Déterminer si la file est vide (opération isEmpty) boolean
isEmpty()
– Enfiler un élément : Ajouter un nouvel élément en queue de la
file (opération add). void enqueue( Object o )
– Défiler un élément : Supprimer l’élément en tête de la file
(opération remove). Object dequeue()
– Renvoyer la valeur de l’élément qui se trouve en tête de la file
(opération queueFront)
• Notons qu'il n’y a aucune limite théorique au nombre
d’éléments d'une file et qu'il est interdit de défiler ou de
demander la valeur d’une file vide.
7. USEK
Faculté
d'Ingénierie
GIN231 - 201120
Implantation de la structure file
• En général, les langages de programmation n’ont
pas d’implantation directe de files. Il faut donc en
faire une implantation logicielle en utilisant les
structures de données primitives offertes par le
langage cible.
• Il existe plusieurs façons pour implanter une
structure de file, nous allons en considérer deux :
– la représentation contiguë (ou représentation par un
tableau).
– la représentation chaînée (ou par une liste chaînée).
8. USEK
Faculté
d'Ingénierie
GIN231 - 201120
Implémentation
Implémentation du TDA file
basée sur un tableau statique
• file d'entiers tableau d'entiers.
• Taille maximale de la file = Taille du tableau = 10
• Profondeur de la file = Nombre d'éléments effectifs dans le tableau = 5
• Indice de la tête de la file = 0
• Indice de la queue de la file = 4
• Nombre d'éléments effectifs = indice de queue – indice de tête + 1 = 5
Enfilement
Défilement
9. USEK
Faculté
d'Ingénierie
GIN231 - 201120
Implémentation du TDA file
basée sur un tableau statique
• Problème de tassement :
– Malgré la simplicité de l'implémentation précédente, son
utilisation conduit à un problème connu sous le nom de
tassement vers la droite. En effet, l'incrémentation de
l'index de début (front) à chaque défilement, conduit à la
"perte" d'une case du tableau. Après un certain nombre de
défilements, la file semble être pleine alors qu'elle est
vide.
10. USEK
Faculté
d'Ingénierie
GIN231 - 201120
Implémentation du TDA file
basée sur un tableau statique
• Solution : décalage
– Cette solution résout notre problème mais au prix
fort. En effet, l'opération de défilement ne se fait
plus en un temps constant mais en temps linéaire.
• Une autre solution consiste à conférer au
tableau un comportement circulaire.
11. USEK
Faculté
d'Ingénierie
GIN231 - 201120
11
Tableau Circulaire-Circular arrays
• Nous pouvons traiter le tableau contenant les éléments la
file d'attente comme circulaire (joints aux extrémités)
44 55 11 22 33
0 1 2 3 4 5 6 7
myQueue:
rear = 1 front = 5
• Des éléments ont été ajoutés à cette file d'attente dans
l'ordre 11, 22, 33, 44, 55, et sera supprimée dans le même
ordre
• Use: front = (front + 1) % myQueue.length;
and: rear = (rear + 1) % myQueue.length;
12. USEK
Faculté
d'Ingénierie
GIN231 - 201120
Représentation de la file d'attente circulaire
10
0
2
4
1
3
f, r
(a)
10
0
2
4
1
3
20
30
f
r
(b)
Après insertion 20 & 30
10
0
2
4
1
3
20
30
f
r
40
50
Après insertion 40 & 50
(c)
10
f
20 30
r
40 50
0 1 2 3 4
10
f
20 30
r
10
f
r
0 1 2 3 4
0 1 2 3 4
13. USEK
Faculté
d'Ingénierie
GIN231 - 201120
13
Représentation de la file d'attente
circulaire(suite…)
f
r
0
2
4
1
3 30
40
50
(d)
Après defilement 10 & 20
f
r
0
2
4
1
3 30
40
50
60
(e)
Après enfilement 60
f
30
r
40 50
0 1 2 3 4
f
30
r
40 5060
0 1 2 3 4
15. USEK
Faculté
d'Ingénierie
GIN231 - 201120
Implémentation du TDA file
basée sur un tableau statique
• Pour implémenter une file par un tableau
circulaire nous devons respecter ce qui suit:
– on incrémente l’indice front
de la file à chaque suppression
on incrémente l’indice rear
de la file à chaque insertion .
– Si l’un ou l’autre index atteint
la dernière case, on retombe
sur la position 0 au prochain
décalage.
17. USEK
Faculté
d'Ingénierie
GIN231 - 201120
Implémentation du TDA file
basée sur un tableau statique
• Le seul problème que nous avons avec cette stratégie est de
déterminer si la file est vide et si la file est pleine.
• Dans certain cas, cela n'est pas évident.
En effet, dans les 2 situations suivantes nous avons : Rear < Front ;
ce qui signifie que la pile est vide !
• Solution : Ajouter un attribut length qui a comme rôle de stocker le
nombre d’éléments de la file.
18. USEK
Faculté
d'Ingénierie
GIN231 - 201120
18
Files d'attente pleines et vides
• Si la file d'attente étaient de devenir complètement plein,
il devrait ressembler à ceci :
• Si nous étions alors de supprimer tous les huit éléments,
faisant la file d'attente complètement vide, il devrait
ressembler à ceci:
44 55 66 77 88 11 22 33
0 1 2 3 4 5 6 7
myQueue:
rear = 4 front = 5
0 1 2 3 4 5 6 7
myQueue:
rear = 4 front = 5
This is a problem!
19. USEK
Faculté
d'Ingénierie
GIN231 - 201120
Full and empty queues: solutions
• Solution #1: Gardez une variable supplémentaire
• Solution #2 (Un peu plus efficace) Garder un écart entre
les éléments: considérons la file d'attente pleine quand
elle a n-1 éléments
44 55 66 77 88 11 22 33
0 1 2 3 4 5 6 7
myQueue:
rear = 4 front = 5count = 8
44 55 66 77 11 22 33
0 1 2 3 4 5 6 7
myQueue:
rear = 3 front = 5
23. USEK
Faculté
d'Ingénierie
GIN231 - 201120
Implementation Tableau Circulaire
• Quand un élément est ajoute dans une file, la
valeur de rear est incrémenté
Mais il faut prendre en compte la nécessité de
la boucle arrière à l'indice 0:
rear = (rear+1) % queue.length;
• Est-ce la mise en œuvre éventail aussi atteindre
la capacité du tableau?
24. USEK
Faculté
d'Ingénierie
GIN231 - 201120
Exemple: tableau de longueur 4
Qu'arrive-t-il?
rear
front
3
queue
count
1
2
0 321
rear
front
4
queue
count
2
2
0 321
Supposons que nous essayons
d'ajouter un élément à une file
d'attente mis en œuvre par un
tableau de longueur 4
cq
cq
La file d'attente est
maintenant complète.
Comment pouvez-vous dire?
25. USEK
Faculté
d'Ingénierie
GIN231 - 201120
6-25
Ajouter une autre cellule !
Besoin d’augmenter la taille …
rear
front
4
queue
count
2
2
0 321
rear
front
4
queue
count
2
2
0 321 4 765
Nous ne pouvons pas
simplement doubler la taille
du tableau: propriétés de la
file d'attente circulaire
seront perdus
Ces emplacements
devraient être en
service
cq
cq
29. USEK
Faculté
d'Ingénierie
GIN231 - 201120
Queues
Array-based Queue
• Use an array of size N in a circular fashion
• Two variables keep track of the front and rear
f index of the front element
r index immediately past the rear element
• Array location r is kept empty
Q
0 1 2 rf
normal configuration
Q
0 1 2 fr
wrapped-around configuration
30. USEK
Faculté
d'Ingénierie
GIN231 - 201120
Queues 30
Queue Operations
• We use the modulo
operator
(remainder of
division)
Static int size()
return (N - f + r) % N
Static boolean isEmpty()
return (f == r)
Q
0 1 2 rf
Q
0 1 2 fr
31. USEK
Faculté
d'Ingénierie
GIN231 - 201120
Queues 31
Queue Operations (cont.)
static enqueue(int o)
if size() = N - 1
throw FullQueueException
else
Q[r] o
r (r + 1) % N
• Operation enqueue
throws an exception if
the array is full
• This exception is
implementation-
dependent
Q
0 1 2 rf
Q
0 1 2 fr
32. USEK
Faculté
d'Ingénierie
GIN231 - 201120
Queues
Queue Operations (cont.)
• Operation dequeue
throws an exception if
the queue is empty
• This exception is
specified in the queue
ADT
Static int dequeue()
if isEmpty()
throw EmptyQueueException
else
o Q[f]
f (f + 1) % N
return o
Q
0 1 2 rf
Q
0 1 2 fr
33. USEK
Faculté
d'Ingénierie
GIN231 - 201120
Implementation
• Une file d'attente utilise un tableau circulaire.
Brièvement, un tableau circulaire est créée avec
une variable d'indice qui s'incrémente comme
suit: :
• I = (I+1) % MAX_SIZE
• Les variables Instance de la Classe sont:
– private int front
– private int rear
– private size
– private final int MAX_SIZE
– private Object[] q
36. USEK
Faculté
d'Ingénierie
GIN231 - 201120
Implantation de la TDA file basée sur
les listes chaînées
• L’implantation des files basée sur les listes
chaînées est appropriée pour les applications
où la taille de la file n'est pas fixée à l'avance.
• Nous allons considérer deux implantations :
– la première basée sur une liste simplement
chaîné,
– la deuxième basée sur une liste circulaire.
37. USEK
Faculté
d'Ingénierie
GIN231 - 201120
Implantation de la TDA file basée sur
une liste simplement chaînée
• Nous allons utiliser une liste simplement chaînée et deux références
front et rear qui représente respectivement la tête et la queue de la
file.
• Dans cette implémentation, l'enfilement d'un nouvel élément se
fait après l'élément référencé par rear tandis que le défilement se
fait par la suppression de l'élément référencé par front.
• La file est vide quand rear et front ont tous les deux la valeur null.
front rear
38. File avec une Liste-Linked Queue
Implementation Dynamique (Reference-based)
Chaque element a 2 champs: value et next
Creer et effacer des objets Dynamiquement
2
next
7
next
Front
4
next
5
next
null
Rear
40. USEK
Faculté
d'Ingénierie
GIN231 - 201120
La File Apres Ajout d’un Element
count
5
rear
front
.
Nouvel élément est ajouté dans un noeud à la fin de la liste, rear point
vers le nouveau nœud, et count est incremente
q
41. USEK
Faculté
d'Ingénierie
GIN231 - 201120
TDA file - Code
public class Queue {
int size
class Element {
int data; // ELEMENT'S DATA
Element next; // REFERENCE TO THE NEXT ELEMENT
Element(int value) {
data = value;
next = this;
}
}
private Element rear = null; // queue (fin) de file
private Element front = null; // queue (fin) de file
public Queue() {
rear = null;
}
42. USEK
Faculté
d'Ingénierie
GIN231 - 201120
TDA file - Code
public boolean isEmpty() {
return queue == null;}
public int size() {
return size;}
public void add(int value) {
Element tmp;
tmp = new Element(value);
if (!isEmpty()){
// si la file n'est pas vide
rear.next = tmp;
rear = tmp;
}
}
43. USEK
Faculté
d'Ingénierie
GIN231 - 201120
TDA file - Code
public Object remove() {
if (isEmpty())
System.exit(0);
Object x= front.data;
// si la file contient un élément
if (front.next == rear)
rear = null;
else
front = front.next.next;
}
return x;
}
public int queueFront() {
if (isEmpty())
System.exit(0);
return rear.next.data;
}
}
44. USEK
Faculté
d'Ingénierie
GIN231 - 201120
Implantation de la TDA file basée sur
une liste simplement chaînée circulaire
• L'utilisation d'une liste circulaire permet de faire
l'économie d'une référence.
• Dans cette implémentation,
– la référence queue se réfère à la queue de file.
– la référence queue.next se réfère sur la tête de file.
– L'enfilement d'un nouvel élément se fait entre queue
et queue.next tandis que le défilement se fait par la
suppression de l'élément pointé par queue.next.
• La file est vide quand queue se réfère à null.
45. USEK
Faculté
d'Ingénierie
GIN231 - 201120
Implantation de la TDA file basée sur
une liste simplement chaînée circulaire
• Etapes à suivre pour réaliser un enfilement dans une
file vide :
– Création d'un nouveau nœud (référencé par tmp sur le
schéma).
– Initialisation de ce nœud (valeur et lien).
– Enfilement par ajustement des liens.
queue tmp queue tmp queue tmp
46. USEK
Faculté
d'Ingénierie
GIN231 - 201120
Implantation de la TDA file basée sur
une liste simplement chaînée circulaire
• Etapes à suivre pour réaliser un défilement :
– La tête de file est le nœud pointé référencé
queue.next.
– Ajuster les liens.
queue queue queue
47. USEK
Faculté
d'Ingénierie
GIN231 - 201120
Implantation de la TDA file basée sur
une liste simplement chaînée circulaire
• Etapes à suivre pour réaliser un enfilement dans une file
non vide :
– Création d'un nouveau nœud (référencé par tmp sur le schéma).
– Initialisation de ce nœud (valeur et lien).
– Enfilement par insertion de tmp entre queue et queue.next.
queue tmp queue tmp queue
queue tmp
48. USEK
Faculté
d'Ingénierie
GIN231 - 201120
Queue-File: Implémentation Liste
chainée Circulaire
• implementations possible de la file
– Une liste chainee circulaire avec une seule reference au
dernier element
• A reference to the back
A reference-based implementation de la file base sur les references: b) Liste circulaire linaire avec
une seule reference
52. USEK
Faculté
d'Ingénierie
GIN231 - 201120
TDA file - Code
public class Queue {
class Element {
int data; // ELEMENT'S DATA
Element next; // REFERENCE TO THE NEXT ELEMENT
Element(int value) {
data = value;
next = this;
}
}
private Element queue = null; // queue (fin) de file
public Queue() {
queue = null;
}
53. USEK
Faculté
d'Ingénierie
GIN231 - 201120
TDA file - Code
public boolean isEmpty() {
return queue == null;}
public int size() {
return size;}
public void add(int value) {
Element tmp;
tmp = new Element(value);
if (!isEmpty()){
// si la file n'est pas vide
tmp.next = queue.next;
queue.next = tmp;
}
queue = tmp;
}
54. USEK
Faculté
d'Ingénierie
GIN231 - 201120
TDA file - Code
public void remove() {
if (isEmpty())
System.exit(0);
// si la file contient un élément
if (queue.next == queue)
queue = null;
else
queue.next = queue.next.next;
}
public int queueFront() {
if (isEmpty())
System.exit(0);
return queue.next.data;
}
}
55. USEK
Faculté
d'Ingénierie
GIN231 - 201120
Queue Example
public Queue<String> findMatches (Scanner input,
String target)
{
Queue<String> q = new LinkedList<String>();
while (input.hasNextLine ())
{
String line = input.nextLine ();
if (line.indexOf (target) >= 0 )
q.add (line);
}
return q;
}
Returns a queue of
all the lines that
contain target
public void process (Queue<String> q)
{
while (! q.isEmpty ())
{
String s = q.remove ();
... // process s
}
}
Processes the
contents of q
(leaves the
queue empty)
56. USEK
Faculté
d'Ingénierie
GIN231 - 201120
Exercices
• Consulter les classes relatives aux files dans le package java.util.
• Implémenter la TDA file en utilisant un tableau statique "circulaire".
• Implémenter la TDA file en utilisant une liste simplement chaînée.
• Ajouter aux implémentations de la TDA file les trois opérations de base suivantes :
– makeEmpty : supprimer tous les éléments de la file
– queueFrontAndRemove : défiler et retourner l'élément défilé
– search : retourne la position dans la file d'une valeur reçue en argument. Retourner -1 si la
valeur n'existe pas dans la file.
• Implémenter la TDA file de priorité. Utiliser un attribut de type entier positif pour indiquer la
priorité.
• Ecrire une méthode qui permet de comparer le contenu d’une pile à celui d’une file. Si les éléments
de la pile de son sommet vers sa base, sont les mêmes que ceux de la file de sa tête vers sa queue,
alors la méthode retourne la valeur true, sinon elle retourne false.
57. USEK
Faculté
d'Ingénierie
GIN231 - 201120
Application
• Vérification de Palindromes :
– Nous introduisons les caractères de la chaîne dans
une pile et une file.
– Nous comparons le sommet de la pile au sommet
de la file.
• Si les deux caractères sont égaux, on les supprime et on
répète le test jusqu’à ce que les deux structures soient
vides. Auquel cas, la chaîne est un palindrome.
• Si les deux caractères ne sont pas égaux, la chaîne n’est
pas un palindrome.
58. USEK
Faculté
d'Ingénierie
GIN231 - 201120
Queues 58
Application: Round Robin Schedulers
• We can implement a round robin scheduler using a
queue, Q, by repeatedly performing the following steps:
1. e = Q.dequeue()
2. Service element e
3. Q.enqueue(e)
The Queue
Shared
Service
1. Deque the
next element
3. Enqueue the
serviced element
2. Service the
next element
Hinweis der Redaktion
Queue() and isEmpty() is self explanatory. Rear is initialized to –1. Front initialized to 0. Size = 0. Q = new Object[MAX_SIZE].