La structure de PILE Option Info - MPSI 2016 La structure de PILE De quoi s’agit-il ? Une pile d’assiettes ... empiler dépiler sommet LIFO = Last In First Out En anglais : STACK La structure de PILE Quelques Exemples Mise en œuvre de la récursivité Parcours en profondeur d’un arbre binaire Langage PostScript Historique des modifications (fonction “undo”) Historique des pages web visitées Vérification du parenthésage Evaluation d’expression post-fixées Calcul de l’enveloppe convexe par l’algorithme de Graham La structure de PILE Syntaxe Constructeurs new : unit → ’a stack crée une pile (initialement vide) push : ’a → ’a stack → ’a stack empile un élément Sélecteur pop : ’a stack → ’a (erreur si pile vide) dépile l’élément au sommet Prédicat is_empty : ’a stack → bool teste si une pile est vide La structure de PILE Implémentation 1 Enregistrement à deux champs : un vecteur sur-dimensionné, pour stocker les données un entier, pour indiquer le sommet de la pile type ’a pile = {c : ’a vect ; mutable s : int} ; ; → Taille et type de la pile sont fixés lors de sa création. La structure de PILE Implémentation 2 Enregistrement à un seul champ : une liste mutable type ’a stack = {mutable c : ’a list} ; ; → Ni la taille, ni le type ne sont fixés à la création. La structure de PILE Quelle implémentation choisir ? Lorsqu’un nouveau type de données est créé (ici : ’a stack), quelques fonctions de manipulation de base (ici : new, push, pop, is_empty) sont mises à la disposition du programmeur. Ces fonctions constituent en quelque sorte une interface entre le programmeur et la structure intime des objets qu’il manipule. Le programmeur n’a pas, en général, à connaître le détail de l’implémentation choisie, pourvu qu’il sache quelles sont les fonctions disponibles, le nombre et les types des arguments qu’elles acceptent, ainsi que le type du résultat qu’elles renvoient. Conséquence importante : si l’implémentation venait à être modifiée, les programmes qui en dépendaient n’ont pas à être rectifiés (ils doivent seulement être recompilés, ou ré-interprétés). La structure de PILE Utilisation d’une pile : exemple 1 expression infixée : 3 + 2 expression postfixée : 3 2 + expression infixée : (3 + 2) × (4 + 1) expression postfixée : 3 2 + 4 1 + × expression infixée : 3 + 2 × (4 + 1) expression postfixée : 3 2 4 1 + × + La structure de PILE Evaluation d’une expression postfixée On considère une expression algébrique, exclusivement composée de valeurs numériques et de symboles d’opérations (addition, multiplication, ...) L’algorithme d’évaluation d’une telle expression repose sur l’utilisation d’une pile : On parcourt l’expression de gauche à droite Pour chaque symbole rencontré, deux cas possibles : valeur → empilée opérateur → les deux opérandes sont dépilés, le résultat est empilé Quand le parcours de l’expression se termine, le résultat est au sommet de la pile La structure de PILE Exemple d’évaluation 3241 + ×+ La structure de PILE Exemple d’évaluation 3241 + ×+ La structure de PILE Exemple d’évaluation 3241 + ×+ La structure de PILE Exemple d’évaluation 3241 + ×+ La structure de PILE Exemple d’évaluation 3241+ × + La structure de PILE Exemple d’évaluation 3241 + ×+ La structure de PILE Exemple d’évaluation 3241 + ×+ La structure de PILE Exemple d’évaluation 3241 + ×+ La structure de PILE La même chose en CAML type symbole = V of int | OP of char;; Type symbole defined. let eval expr = let n = vect_length expr in let s = new () in for i = 0 to n-1 do match expr.(i) with | V x → push x s | OP c → let x2 = pop s in let x1 = pop s in match c with | ‘+‘ → push (x1 + x2) s | ‘-‘ → push (x1 - x2) s | ‘*‘ → push (x1 * x2) s | _ → failwith "not implemented" done; pop s ;; eval : symbole vect → int = <fun> La structure de PILE Utilisation d’une pile : exemple 2 Une partie C du plan est dite convexe lorsque : ∀ (M, N ) ∈ C 2 , [M, N ] ⊂ C La structure de PILE Enveloppe convexe Si A est une partie quelconque du plan, on appelle enveloppe convexe de A (convex hull, en anglais) la “plus petite” partie convexe contenant A (c’est l’intersection de toutes les parties convexes du plan qui contiennent A). On la note conv (A) . La structure de PILE Enveloppe convexe d’une partie finie Dans le cas d’une partie finie A, on peut montrer que conv (A) est un polygone convexe dont les sommets sont certains points de A. L’algorithme de Graham prend A en entrée et calcule la liste des sommets de conv (A) . La structure de PILE Algorithme de Graham : pseudo-code P0 = point en bas à gauche Tri des autres points par angle polaire croissant : P1 , · · · , Pn − 1 Empiler P0 , P1 , P2 POUR i = 3 à n − 1 FAIRE TANT QUE (SubTop, Top, Pi ) tourne à droite FAIRE dépiler fin TANT QUE empiler Pi fin POUR La structure de PILE L’algorithme de Graham pas à pas ... La structure de PILE L’algorithme de Graham pas à pas ... La structure de PILE L’algorithme de Graham pas à pas ... La structure de PILE L’algorithme de Graham pas à pas ... La structure de PILE L’algorithme de Graham pas à pas ... La structure de PILE L’algorithme de Graham pas à pas ... La structure de PILE L’algorithme de Graham pas à pas ... La structure de PILE L’algorithme de Graham pas à pas ... La structure de PILE L’algorithme de Graham pas à pas ... La structure de PILE L’algorithme de Graham pas à pas ... La structure de PILE L’algorithme de Graham pas à pas ... La structure de PILE L’algorithme de Graham pas à pas ... La structure de PILE Algorithme de Graham : complexité Détermination de P0 → O (n ) . Tri → O (n log (n )) . Parcours → O (n ) . En effet, pour tout i ∈ {0, · · · , n − 1} : Pi est empilé 1 fois, Pi est dépilé au plus 1 fois d’où au plus 2n opérations push / pop Total : O (n log (n )) La structure de PILE Travail à faire ... Deux implémentations de la structure de pile : définir le type ’a stack puis écrire les fonctions de base new, push, pop, is_empty. Ecrire quatre nouvelles fonctions, en s’appuyant exclusivement sur les fonctions de base ci-dessus : 1 2 3 dup : ’a stack → unit duplique l’élément au sommet swap : ’a stack → unit permute les deux éléments au sommet rot_down : ’a stack → unit, rot_up : ’a stack → unit effectuent des permutations circulaires sur la pile La structure de PILE Travail à faire (suite) Vérification du parenthésage d’une expression algébrique : écrire une fonction acceptant en entrée une chaîne de caractères, qui détermine si le parenthésage est correct ou non. En cas de parenthésage incorrect, l’indice de la première parenthèse incorrecte sera indiqué. Programmer l’algorithme de Graham. Et pour les plus gourmand(e)s ... On génère aléatoirement (et uniformément) un ensemble de N points dans un carré : étudier expérimentalement la distribution du nombre de sommets de l’enveloppe convexe de cet ensemble. La structure de PILE \˜b“y´e La structure de PILE