Les Files et Les Piles PLAN - Définitions - Implémentations - Exemples d'application Derdouri Z. & Hidouci W.K. / ESI / ALSDD
Définitions File = collection (ensemble) d'éléments gérée en FIFO (First In First Out) - Pile = collection (ensemble) d'éléments gérée en LIFO (Last In First Out) - stack Utilisations Files systèmes d'exploitation simulations Piles compilation autres... autres... gestion des imbrications empilement enfilement défilement tête dépilement sommet Derdouri Z. & Hidouci W.K. / ESI / ALSDD
Exemple de File Une file contenant elts CCC BBB AAA après l'enfilement de DDD DDD CCC BBB AAA après l'enfilement de EEE EEE DDD CCC BBB AAA après un défilement EEE DDD CCC BBB après un e défilement EEE DDD CCC Derdouri Z. & Hidouci W.K. / ESI / ALSDD
Exemple de Pile sommet Une pile contenant elts CCC BBB AAA sommet après l'empilement de DDD DDD CCC BBB AAA sommet après l'empilement de EEE EEE DDD CCC BBB AAA sommet après un dépilement DDD CCC BBB AAA sommet après un e dépilement CCC BBB AAA Derdouri Z. & Hidouci W.K. / ESI / ALSDD 4
Modèle des Files CreerFile( var F:File ) ==> File initialise la file F à vide Enfiler( x:tqlq; var F:File ) insère x en de la file F File x Elt ==> File Defiler( var x:tqlq; var F:File ) File ==> Elt x File retire dans x, l'élément en tête de la file F FileVide( F:File ) : Booleen File ==> Bool FilePleine( F:File ) : Booleen File ==> Bool testent l'état de F (vide ou pleine) Conditions: Défiler est définie si not FileVide Enfiler est définie si not FilePleine Derdouri Z. & Hidouci W.K. / ESI / ALSDD 5
Modèle des Piles CreerPile( var P:Pile ) ==> Pile initialise la pile P à vide Empiler( x:tqlq; var P:Pile ) insère x au sommet de la pile P Pile x Elt ==> Pile Depiler( var x:tqlq; var P:Pile ) Pile ==> Elt x Pile retire dans x, l'élément du sommet de la pile P PileVide( P:Pile ) : Booleen Pile ==> Bool PilePleine( P:File ) : Booleen Pile ==> Bool testent l'état de P (vide ou pleine) Conditions: Dépiler est définie si not PileVide Empiler est définie si not PilePleine Derdouri Z. & Hidouci W.K. / ESI / ALSDD 6
Implémentation d'une File en dynamique : v v v v4 v5 tête File Une file d'entiers en C struct maillon { int val; struct maillon *adr; }; typedef struct { struct maillon *, *; } File; void CreerFile( File *pf ) { pf-> = NIL; pf-> = NIL; } int FileVide( File f ) { retrun (f. == ); } int FilePleine( File f ) { return ; } /* jamais pleine */ /* pour simplifier */ Derdouri Z. & Hidouci W.K. / ESI / ALSDD 7
Implémentation d'une File en dynamique : v v v v4 v5 x tête int Enfiler( int x, File *pf ) { struct maillon *p; if ( FilePleine(*pf) ) return ; /* enfilement impossible car FilePleine */ p = malloc( sizeof(*p) ); if ( p == ) return ; /* enfilement impossible: malloc a échoué */ p->val = x; p->adr = ; if ( pf-> ) pf->->adr = p; /* */ else pf-> = p; File p } pf-> = p; /* */ return ; Derdouri Z. & Hidouci W.K. / ESI / ALSDD 8
Implémentation d'une File en dynamique : v v v v4 v5 x tête File int Defiler( int *x; File *pf ) { struct maillon *p; if ( FileVide(*pf) ) return ; *x = pf->->val; /* */ p = pf->; pf-> = pf->->adr; /* */ free( p ); p = ; if ( pf-> == ) pf-> = ; } return ; Derdouri Z. & Hidouci W.K. / ESI / ALSDD 9
Implémentations d'une File en statique Représentation par leaux le nombre maximum d'éléments est fixé une fois pour toute approches : par décalage pas efficace par flots pas pratique, juste pour introduire la prochaine par leaux circulaire représentation standard (pratique et efficace) Derdouri Z. & Hidouci W.K. / ESI / ALSDD
File en statique : «Par décalages» #define N typedef struct { int[n] ; int ; } File; v4 v v v N- tête = l'indice (fixe) = l'indice du dernier elts File défiler = décalages vers le bas, puis (--) N- enfiler : rapide (++) FileVide : ( == -) v4 v FilePleine : ( == N-) v après défilement d'un élément Derdouri Z. & Hidouci W.K. / ESI / ALSDD
File en statique : «Par flots» #define N typedef struct { int[n] ; int, ; } File; tête = s'incrémente à chaque défilement v4 v v v N- File = s'incrémente à chaque enfilement N- v4 + pas de décalages v v - l'espace libéré est perdu après défilement d'un élément Derdouri Z. & Hidouci W.K. / ESI / ALSDD
File en statique : «Par leau circulaire» même principe que l'approche par flots (même déclaration) les incrémentations se font modulo N réutilisation des cases libérées. efficace : pas de boucle v4 v v v 5 4 5 réutilise l'espace perdu par les défilements # define N typedef struct { int[n] ; int, ; } File; File contenant 4 éléments v4 5 v 4 v v v5 après enfilement de v5 Derdouri Z. & Hidouci W.K. / ESI / ALSDD
Problème : FilePleine vs FileVide ( = ( + mod N) dans les deux cas) v4 5 v 4 v v File contenant 4 éléments 5 v4 5 v 4 v v v5 après enfilement de v5 v4 v v v v6 v5 5 4 après enfilement de v6 : FilePleine v v 5 4 v 5 4 5 4 4 File contenant éléments après défilement de v après défilement de v : FileVide Derdouri Z. & Hidouci W.K. / ESI / ALSDD 4
Solution : sacrifier un élément par convention, l'élément d'indice sera sacrifié le er elt se trouve alors à l'indice (+ mod N) v4 v v 5 4 5 v4 v v 5 4 FilePleine ssi : = (+ mod N) v v v5 File contenant 4 éléments après enfilement de v5 : FilePleine 5 4 5 4 FileVide ssi : = v File contenant élément après défilement de v : FileVide Derdouri Z. & Hidouci W.K. / ESI / ALSDD 5
File en statique : Programmes C void CreerFile ( File *pf ) { pf-> = N-; pf-> = N-; } int FileVide( File F ) { return (F. == F.); } int FilePleine( File F ) { return ( F. == (F.+ % N) ); } int Enfiler( int x, File *pf ) { if ( FilePleine(*pf) ) return ; pf-> = (pf-> + ) % N; pf->[pf->] = x; return ; } int Defiler( int *x, File *pf ) { if ( FileVide( *pf ) ) return ; pf-> = (pf->+) % N; *x = pf->.[pf->]; return ; } Derdouri Z. & Hidouci W.K. / ESI / ALSDD 6
Implémentation d'une Pile en dynamique Pile v5 v4 v v v struct maillon) { int val; struct maillon *adr; }; typedef struct maillon *Pile; void CreerPile( Pile *p ) { *pp = ; } int PileVide( Pile p) { return (P==); } int PilePleine(Pile p) { return ; } int Empiler( int x, Pile *p) { struct maillon *q; if ( PilePleine(*p) ) return ; q = malloc( sizeof(*q) ); q->val = x; q->adr = *p; *p = q; return ; } int Depiler( int *x, Pile *p ) { struct maillon *q; if ( PileVide(*p) ) return ; *x = (*p)->val; q = *p; *p = (*p)->adr; free(q); return ; } Derdouri Z. & Hidouci W.K. / ESI / ALSDD 7
Implémentation d'une Pile en statique 4 v v v sommet Pile typedef struct { int[n] ; int sommet; } Pile; void CreerPile( Pile *p ) { p->sommet = -; } int PileVide( Pile p ) { return (p.sommet == -); } int PilePleine( Pile p) { return (p.sommet == N-); } int Empiler( int x, Pile *p ) { if ( PilePleine(*p) ) return ; p->[++(p->sommet) ] = x; return ; } int Depiler( int *x, Pile *p ) { if ( PileVide(*p) ) return ; *x = p->[p->sommet--]; return ; } Derdouri Z. & Hidouci W.K. / ESI / ALSDD 8
Exemple d'application manipulation d'expression arithmétique Notation infixée: <exp> <opérateur> <exp> ex : a + b, a + b*c, (a+b) * c, ~a + b Notation préfixée: <opérateur> <exp> <exp> ex : + a b, + a *bc, * +ab c, + ~a b Notation postfixée: <exp> <exp> <opérateur> ex : a b +, a bc* +, ab+ c *, a~ b + Derdouri Z. & Hidouci W.K. / ESI / ALSDD 9
Evaluation d'une exp postfixée EVAL_Postfixe( T:chaine ) : Reel i := ; CreerPile(p); TQ T[i] <> '#' SI Operande( T[i] ) Empiler( p,t[i] ) SINON /* donc c'est un opérateur */ SI Binaire( T[i] ) Depiler(p,x); Depiler(p,y); Empiler( p, Calcul( x, T[i], y ) ); SINON/* donc uniaire */ Depiler(p,y); Empiler( p, Calcul(, T[i], y ) ); FSI FSI; i := i+ FTQ; SI Non PileVide(p) : Depiler( p, x ) Sinon x:= FSI; EVAL_Postfixe := x Principe: SI opérande l'empiler SI Opérateur dépiler le nb de param. requis et empiler le résultat. A la fin : Le résultat final se trouve au sommet de pile Derdouri Z. & Hidouci W.K. / ESI / ALSDD
Evaluation d une expression infixée (plus complexe) 5 * (((9+8)*(4*6))+7) - empiler(5) - empiler(9) - empiler(8) 4 - empiler( dépiler() + dépiler() ) 5 - empiler(4) 6 - empiler(6) 7 - empiler(dépiler() * dépiler()) 8 - empiler(dépiler() * dépiler()) 9 - empiler(7) - empiler(dépiler() + dépiler()) - empiler(dépiler() * dépiler()) - écrire(dépiler()) 8 9 9 5 5 5 6 4 4 7 7 7 5 5 5 4 7 7 48 48 5 5 5 45 5 75 Derdouri Z. & Hidouci W.K. / ESI / ALSDD
Transformation infixée --> postfixée - Règles de transformation - Les opérandes gardent le même ordre dans les deux notations Les opérateurs sont empilés, en prenant la précaution de dépiler d'abord tous les opérateurs plus prioritaires les dépilements se font dans la chaîne postfixée '(' est empilée sans faire de test ')' Depiler tous les opérateurs dans la chaîne postfixée, jusqu'à trouver une '(', qui sera écartée A la fin, tous les opérateurs encore dans la pile seront dépilés dans la chaîne postfixée. Derdouri Z. & Hidouci W.K. / ESI / ALSDD
a + b * c # --> Transformation infixée --> postfixée - exemple : construction elt / elt - a avancer... a + b * c # --> a + empiler + a + b * c # --> a b + avancer... a + b * c # --> a b * + empiler * a + b * c # --> a b c * + avancer... a + b * c # --> a b c * + dépiler tout Derdouri Z. & Hidouci W.K. / ESI / ALSDD
Transformation infixée --> postfixée - exemples - ~b * c # --> b~ c * ~ * * ne s'empile pas sur ~ prio(*) < prio(~) a / b + c # --> a b / c + a b + c # --> a b c + / + - + + ne s'empile pas sur / prio(+) < prio(/) + ne s'empile pas sur - prio(+) = prio(-) ( + - * / ~ moins unaire Priorité des opérateurs Derdouri Z. & Hidouci W.K. / ESI / ALSDD 4
Trans( Inf : chaine; var post : chaine ) i := ; j := ; CreerPile(p); TQ Inf [ i ] <> '#' SI Inf [ i] = '(' : Empiler(p, '(' ) /*. cas d'une '(' */ SINON SI Operateur( Inf [ i ] ) /*. cas d'un opérateur */ stop := FAUX; TQ Non stop et Non PileVide(p) Depiler(p,x); SI Prio(x) < Prio( Inf[ i] ) Empiler(p,x); stop := VRAI; SINON j++; post[ j ] := x; FTQ Empiler( p, Inf[ i ] ); SINON SI Inf[ i ] = ')' /*. cas d'une ')' */ stop := FAUX; TQ Non stop et Non PileVide(p) Depiler(p, x); SI ( x = '(' ) stop := VRAI SINON post[ ++j ] := x FSI FTQ SINON /* 4. cas d'un opérande */ post[ ++j ] := Inf[ i ] FSI FSI FSI i++; FTQ Derdouri Z. & Hidouci W.K. / ESI / ALSDD 5