2 Les piles - BigBozoid
Structure séquentielle : listes (cas particulier des piles et des files). Structures ...
Structures associatives à tableaux associatifs, tableaux de hachage. .... Donc, par
exemple, la liste (1, 3, 2, 5) est notée en notation formelle : (1, (3, (2, (5, ( ))))).
part of the document
booléen
Calcul
Fonction DuréeEnJour (E d1, d2 : date) : entier
Service
Fonction Lendemain (E d : date) : date
Remarque : Un type abstrait de données ressemble donc fortement à une classe (voir cours de C/C++). Cest dailleurs par des classes quil faudra de préférence définir et manipuler les types abstraits de données.
Historique
Historiquement, les types abstraits de données désignent plutôt des structures abstraites de données :
Structure linéaire à accès direct : tableaux
Structure séquentielle : listes (cas particulier des piles et des files)
Structures arborescente : arbres binaires, arbres quelconques
Structures relationnelles : graphe
Structures associatives à tableaux associatifs, tableaux de hachage.
Nous allons essayer de voir tous ces types abstraits de données. Les tableaux ont déjà été abordés, voyons tout dabord ce que sont les piles et les files.
Les piles
Une pile est une suite ordonnée déléments dans laquelle lajout ou la suppression déléments se fait toujours du même côté.
Pour tous les exercices suivants, on se définit les actions et fonctions de bases sur les piles définies sur la fiche III : Types Abstraits de Données.
Exercice 1
a) Ecrire une fonction qui prend en entrée une pile et retourne le nombre déléments de cette pile.
b) Ecrire une fonction qui prend en entrée une pile et qui sort une autre pile, identique à la pile dentrée.
c) Faire des variantes de b) en écrivant une action qui prend en entrée sortie une pile et qui sort une pile en prenant un élément sur deux
a)
Fonction NombreElement (E p : Tpile ) : entier
Var : n : entier
Début
N=0
Tant que ( !Pilevide (p)) faire
N( N+1
Dépiler(p)
Retourner N
Fin
b)
Action clone (ES p1 : Tpile, p3 : Tpile)
Var : p2 ; p3 : Tpile
Début
CréerPile(p2)
CréerPile(p3)
Tant que ( !PileVide(p1))
Empiler (p2, ValeurSommet(p1))
Dépiler(p1)
Tant que ( !PileVide(p2))
Empiler(p3, ValeurSommet(p2))
Empiler(p1, ValeurSommet(p2)) // car p1 est en ES et on veut la récupérer dans le même état.
Dépiler (p2)
Fin
c)
Action UnSurDeux (ES p1 : Tpile, p3 : Tpile)
Var : p2, p3 : Tpile cpt : entier
Début
Cpt=0 ;
CréerPile(p2) ;
CréerPile(p3) ;
Tant que ( !PileVide(p1))
Si cpt%2=0 alors Empiler (p2, ValeurSommet(i1))
Dépiler(p1)
Cpt++
Tant que ( !PileVide(p2))
Empiler(p3, ValeurSommet(p2))
Dépiler(p2) ;
Fin
Evaluation dexpressions arithmétiques avec les piles
Expressions infixées
Dans lexpression infixées, lopérateur (+ - * / ) est placé entre ses 2 opérateurs. Le problème de lexpression infixée, cest quen lisant au fur et à mesure, on na pas une vision des priorité sur les opérations.
Exemple : 5*3+2 ( 5+3*2
Pour simplifier, dans un premier temps, on peut utiliser les expressions complètement parenthésées (ECP) : Un nombre, ou une variable est une ECP. Si ( est un opérateur et x et y sont des ECP alors (x*y) est un ECP.
Dans une ECP, on na donc plus besoin dintroduire les priorités entre opérateurs car les parenthèses définissent ces priorités.
Voir et faire tourner la fonction donnée évalECP (feuille ci jointe) sur ((((A+B)*C)/D)-(E-F)) avec lenvironnement a=5 ; B=3 ; C=6 ; D=2 ; E=5 ; F=3.
Expressions postfixées
Une expression postfixée (EP) : Une variable, ou un nombre est une EP. Si (est un opérateur et x et y deux EP alors xy( est une EP.
Exemple : 2+3 ( 2.3*
Le but est de mettre au point un algorithme permettant dévaluer une EP (comme évalECP du 2.2.1)
Remarque : Dans lexpression postfixée, lordre des opérateurs donne lordre dans lequel on doit faire les calculs (dès que lon a un opérateur, on sait quil faut faire un calcul et quil est dans lordre)
Idée de lalgorithme dévaluation :
Tant que lon tombe sur une opérande, on empile sa valeur. Dès que lon tombe sur un opérateur, on dépile les deux dernières opérandes, on effectue le calcul et on place le résultat dans la pile. A la fin, la seule valeur présente dans la pile est le résultat de lexpression quil fallait évaluer.
Exercice : faire lalgorithme de evalEP
Fonction evalEP ( E : EP : tableau[MAX] de caractères) : réel
Var : i entier ; vald, valg, résultat : réels ; p : Tpile)
Début
CréerPile(p)
I(0
tant que EP[i] % faire
si variable(EP[i]) alors empiler(p, ValeurSommet(eP[i])
sinon
vald(ValeurSommet(p)
dépiler(p)
valg(ValeurSommet(p)
dépiler(p)
empiler(p, oper(valg, EP[i], vald)
i++
fin tant que
résultat(ValeurSommet(p)
dépiler(p)
retourner(résultat)
fin
Passage dune écriture infixée à une écriture postfixée
Par exemple, on veut passer de lexpression : a*b + c/(d*e) à son expression postfixée ab*cde*/+. Les opérandes apparaissent dans le même ordre dans les deux expressions, donc il nest pas besoin de les stocker dans un temporaire. En revanche, on va stocker les opérateurs dans une pile en faisant attention de les sortir au bon moment.
Entrée EISortie EPPileLit aEcrit avideLit *aEcrit *Lit bEcrit b : ab*Lit +ab*Compare + et * : * (qui est dans la pile) est plus fort, on le sort de la pile et on lécrit dans EP, puis on met + dans la pileLit cécrit c : ab*c+Lit /ab*cCompare + et / : + (qui est dans la pile) est plus faible, on ajoute alors / à la pileLit (ab*cOn ajoute ( à la pile.Lit décrit d : ab*cd+ / (Lit *ab*cdLes deux opérandes sont identiques : on empile : + / ( *Lit eécrit e : ab*cde + / ( *Lit )écrit * : ab*cde*On sort tous les opérateurs de la pile qui sont après ( : donc ici on enlève * et on le met dans EPab*cde*puis on écrit tous les opérateurs de la pile en ne mettant pas (ab*cde*/+cest le résultat final. La pile est vide.
Exercice : Faire lalgorithme de changement décriture (dune expression infixée à une expression postfixée) en vous aidant du tableau explicatif de fonctionnement si dessus.
Les files
La notion de file en algorithme correspond à la notion de file dattente. Une file est donc un ensemble déléments ordonnés. Toute insertion se fait à la fin de la file, et toute suppression se fait en début de file. Seule la valeur en début de file est accessible.
Une file est donc une structure First In First Out (FIFO)
Les primitives
Voir la fiche ASD III : « les types abstraits de données »
Un exemple
Ecriture dune action qui retourne la file inverse dune file passée en entrée sortie.
Action FileInverse (ES F : Tfile)
Var : p : Tpile
Début
CréerPile (p)
Tant que ( !PileVide (p))
Empiler (p, valeurPremier(F))
Défiler (F)
Tant que ( !PileVide(p))
Enfiler (F, valeurSommet(p))
Dépiler (p)
Fin
Les listes
Généralités
Une liste est une suite déléments placés dans un certain ordre. (exemple : (1, 3, 2, 5) (3, 1, 2, 5) (1, 2, 3, 5) sont 3 listes différentes. On peut ajouter ou supprimer un élément en nimporte quelle position dans la liste avec conservation des positions respectives des autres éléments.
On se donne un moyen de parcourir la liste : pour savoir quel est le premier élément, ou bien, étant donné un élément, savoir aller au suivant.
Définitions formelles
Une liste est soit la liste vide (notée ( )), soit un couple composé dune valeur et dune liste (notée (valeur, liste)). Donc, par exemple, la liste (1, 3, 2, 5) est notée en notation formelle : (1, (3, (2, (5, ( ))))).
Une liste est composé dun premier élément et dune sous liste qui est la liste des suivant (elle même composée dun premier élément et dune sous liste, et ainsi de suite).
Primitives
Voir la feuille ASD III sur les types abstraits de données.
En quoi les primitives peuvent être utiles ?
Pour savoir si une liste (ou une sous liste) est vide
Etant donné une liste, on peut obtenir la valeur du premier élément, ou bien obtenir la liste des suivants
Linsertion en-tête dun élément se fait par création dune nouvelle liste à partir dun couple.
Linsertion en milieu de liste se fait par remplacement de la liste des suivants
Primitives de manipulation de listes
Pour cela, on se donne des primitives de manipulation de liste. Voir fiche ASD III types abstraits de données.
Exemple
Affichage des éléments dune liste :
Action Affichage (E L : Tliste)
Var : Adr : Tadresse
Début
Adr ( AdressePremier(L)
Tant que Adr != NULL faire
Ecrire (ValeurElement(L, Adr))
Adr(AdresseSuivant(L, Adr)
Fin
Exercices sur les listes
Exercice 1
On suppose quon a en entrée une liste de TEtudiants, dont un champ sappelle note. Calculer la moyenne de la classe (on suppose que la liste est non vide).
Fonction Moyenne (E L : Tliste) : réel
Var : Adr : Tadresse
Som, cpt : réel
Etd : TEtudiants
Début
Adr(AdressePremier(L)
Som(0
Cpt(0
Tant que Adr != NULL faire
Etd(ValeurElement(L, Adr)
Som(Som+Etd.note
Cpt++
Retourner (Som/Cpt)
Fin
Exercice 2
On suppose quon a en entrée une liste triée par ordre croissant dentiers. Ecrivez laction qui rajoute un entier donné en paramètre à cette liste de façon à ce quelle soit encore triée après insertion.
Action InsertTrié (ES L : Tliste, E Nb : entier)
Var : Adr, Adrpr : Tadresse
Début
Adr(AdressePremier(L)
Si (Adr==NULL ou ValeurElement(L, Adr)(n)
InsérerEnTete(L, Nb)
Sinon
Tant que (AdresseSuivant(L, Adr) ( NULL et n > ValeurElement(L, AdresseSuivant(L, Adr)) )
Adr(AdresseSuivant(L, Adr)
InsérerAprès(L, Nb, Adr)
Fin
Quelques astuces pour des algorithmes simples avec les listes
Pour retourner ladresse de lélément au milieu de la liste, on déplace deux adresses, dadresse en adresse, avec une adresse qui se déplace une fois sur deux
Ainsi, quand lune des adresses arrive à la fin de la liste, lautre adresse est au milieu. On a alors ladresse de lélément au milieu.
Si la liste est triée (des réels par exemple) on obtient donc (en un seul passage de liste et sans avoir à connaître la longueur de la liste) la médiane de la liste.
Pour lexercice 2 : dans ce type dexercice, on est obligé de vérifier une condition, suivant que lon est en début de liste ou non. Pour éviter cela, on peut insérer en début de liste un élément fictif, puis effectuer les opérations à partir du deuxième élément. En fin de calcul, on supprime cet élément fictif.
Exercice 3
Proposer un algorithme qui fait la concaténation de deux listes (en entrée) retournant une liste (en sortie). Par exemple, si lon a les listes (3, 7, 2) et (5, 4) on obtient la liste (3, 7, 2, 5, 4).
Proposer ensuite un algorithme séparant une liste en deux. Etant donné une liste en entrée, un élément sur deux va dans la première liste et un élément sur deux va dans la deuxième liste.
Faire une action de fusion de listes supposées triées par ordre croissant en une troisième liste triée.
Faire, en utilisant au choix les trois actions précédentes une action de tri fusion qui étant donné deux listes en entrée (pas forcément triées) retourne une liste triée.
Action concaténation (E L1 : Tliste, E L2 : Tliste, S L : Tliste)
Var : Adr, AdrS : Tadresse
Début
CréerListe (L)
InsérerEnTete (L, % )
AdrS ( AdressePremier(L)
Adr( AdressePremier(L1)
Tant que Adr `"NULL faire
InsérerAprès (L, ValeurElement(L1, Adr), AdrS)
Adr( AdresseSuivant (L1, Adr)
AdrS( AdresseSuivant (L, AdrS)
Adr(AdressePremier(L2)
Tant que Adr `"NULL faire
InsérerAprès (L, ValeurElement(L2, Adr), AdrS)
Adr(AdresseSuivant(L2, Adr)
AdrS(AdresseSuivant(L, AdrS)
SupprimerEnTete(L)
Fin
Action Séparer (E L : Tliste, S L1 : Tliste, S L2 : Tliste)
Var : Adr, Adr1, Adr2 : Tadresse ; B : booléen
Début
CréerListe(L1)
CréerListe (L2)
B(true
InsérerEnTete(L1, E)
InsérerEnTete(L2, E)
Adr1(AdressePremier(L1)
Adr2(AdressePremier(L2)
Adr(AdressePremier(L)
Tant que Adr`"NULL faire
Si B alors
InsérerAprès(L1, ValeurElement(L, Adr), Adr1)
Adr1(AdresseSuivant(L1, Adr1)
Sinon
InsérerAprès(L2, ValeurElement(L, Adr), Adr2)
Adr2(AdresseSuivant(L2, Adr2)
B( !B
Adr(AdresseSuivant(Adr)
SupprimerEnTete(L1)
SupprimerEnTete(L2)
Fin
Action Fusion (E L1 : Tliste, E L2 : Tliste, S L : Tliste)
Var : Adr1, Adr2, Adr : Tadresse
Début
CréerListe(L)
InsérerEnTete(L, E)
Adr(AdressePremier(L)
Adr1(AdressePremier(L1)
Adr2(AdressePremier(L2)
Tant que (Adr1`"NULL et Adr`"NULL)
Si ValeurElement(L1, Adr1) v alors Adr ( AdresseFilsGauche(A, Adr)
Sinon Adr ( AdresseFilsDroit(A, Adr)
Retourne Adr
Fin
Efficacité des requêtes classiques :
Si larbre nest pas équilibré, les recherches peuvent prendre jusquà N opérations
Dans un arbre équilibré, la longueur des branches est de [log2 N]+1
Donc, comment réaliser un arbre de recherche équilibré ? En utilisant le théorème suivant : A tout ensemble dactions, il existe un arbre équilibré. Comment ? On fait des rééquilibrages progressifs, par rotation de racines.
PAGE
PAGE 10
Les types abstraits de données