IFT-2000: Structures de données Piles et files Dominic Genest, 2009
Les piles et les files Les piles et les files sont des structures où on restreint les opérations à un seul bout; soit le début, soit la fin. Dans le cas dune pile, on oblige à faire les insertions toujours à la même extrémité que les suppressions; comme dans une vraie pile. Dans le cas dune file, on oblige à faire les insertions toujours à lextrémité opposée à celle où lon fait les suppressions; comme dans une vraie file. Dans les deux structures, normalement, on ne permet laccès quau prochain élément supprimable. Dans une pile, plutôt que de dire « insérer », on dit « empiler », et plutôt que de dire « supprimer », on dit « dépiler ». Et dans une file, on dit « enfiler » et « défiler ». Dominic Genest, 2009
Les implémentations des piles et des files Les piles et les files ne sont pas de nouvelles façons dimplémenter des structures de données, ils ne sont que des façons de définir les interfaces et les fonctions. On peut donc utiliser nimporte quelle structure linéaire (tableau statique, dynamique, liste chaînée simple ou double) pour les implémenter. Curieusement, même si cela paraît insignifiant car il ne sagit après tout que de nommer une opération autrement, le fait de parler dune pile ou dune file simplifie grandement lexpression de certains algorithmes. De la même façon, le code qui utilise des structures et leurs fonctions nommées dune telle façon deviendra beaucoup plus clair et facile à déboguer. Dominic Genest, 2009
Une pile par tableau statique #define MAX 1000 typedef enum { OK, Erreur,PilePleine,PileVide } CodeErreur; Typedef enum { FAUX, VIDE } BOOL; typedef struct { Etudiant t[MAX]; int n; } PileDEtudiants; CodeErreur init(PileDEtudiants *p) { p->n=0; return OK; } CodeErreur empiler(PileDEtudiants *p, Etudiant e) { if(p->n==MAX) return PilePleine; p->t[p->n++] = e; return OK; } CodeErreur depiler(PileDEtudiants *p) { if(p->n==0) return PileVide; p->n--; return OK; } CodeErreur dessus(const PileDEtudiants *p, Etudiant *e) { if(p->n==0) return PileVide; *e = p->t[p->n-1]; return OK; } BOOL estVide(const PileDEtudiants *p) { return p->n==0; } Dominic Genest, 2009
Exemples dutilisation de piles et de files Piles: – Parcours en profondeur de graphes – Interpréteurs et compilateurs Files: – Parcours en largeur de graphes. – Tâches en attente pour une ressource temporairement non disponible Dominic Genest, 2009
Files prioritaires Dans une file prioritaire, le prochain élément défilé nest pas nécessairement le premier qui a été enfilé. Un autre critère est employé pour déterminer le prochain à être défilé. Il peut sagir: – Soit dune valeur de priorité explicitement spécifiée lors de lenfilement – Soit de la comparaison dune valeur qui résulte dun calcul sur les données de la file. Par exemple: Létudiant le plus jeune en premier Le point le plus près de lorigine en premier) Dominic Genest, 2009
Files prioritaires Pour implémenter une file prioritaire, on peut: – Soit placer lélément à la bonne place dès lenfilement, de sorte que le défilement se fasse directement sur une extrémité de la structure. Ceci est beaucoup plus efficace, car linsertion selon un certain critère de tri peut se faire par dichotomie (par séparation récursive en deux), nous nous attarderons à ça lors de lintroduction aux arbres binaires. – Soit placer lélément à une extrémité de la structure, de sorte quil faille effectuer la recherche du plus prioritaire lors du défilement. Cela peut être nécessaire lorsque la priorité dépend aussi de données externes, qui peuvent avoir changé depuis lenfilement. Dominic Genest, 2009
Implémentation dune file prioritaire détudiants selon lâge, par tableau statique Dominic Genest, 2009 #define MAX 1000 typedef enum { OK, Erreur,FilePleine,FileVide } CodeErreur; typedef enum { FAUX, VIDE } BOOL; typedef struct { Etudiant t[MAX]; int n; } FileDEtudiants; CodeErreur init(FileDEtudiants *f) { f->n=0; return OK; } CodeErreur emfiler(FileDEtudiants *f, Etudiant e) { int i, pos; if(f->n==MAX) return FilePleine; for(pos=0;pos n && f- >t[pos].age<e.age;pos++); for(i=f->n;i>pos;i--) f->t[i]=f->t[i-1]; f->t[pos] = e; f->n++; return OK; } CodeErreur defiler(FileDEtudiants *f) { if(f->n==0) return FileVide; f->n--; return OK; } CodeErreur prochain(const FileDEtudiants *f, Etudiant *e) { if(f->n==0) return FileVide; *e = f->t[f->n-1]; return OK; } BOOL estVide(const FileDEtudiants *f) { return f->n==0; }