Chapitre IV. Structures linéaires (piles, files, listes chaînées)

Slides:



Advertisements
Présentations similaires
Chapitre annexe. Récursivité
Advertisements

Masters IIGLI et IGLII – Programmation générique et conception objet – – Claude Montacié 1 Cours n° 5 Structures de données abstraites.
Initiation à la programmation et algorithmique cours 4
Le langage Z Pr ZEGOUR DJAMEL EDDINE
Sémantique des déclarations pour le langage Z minimal
Introduction: Concepts de la programmation
Piles, files et listes: notions théoriques
Fonctions & procédures
Structures de données et complexité
Structures de données et complexité LIFO – FILO – FIFO – etc…
Au programme du jour …. Un peu plus de structures de données
Types de données abstraites
Cours n° 8 Conception et Programmation à Objets
Approfondissement du langage
Algorithme et structure de données
INTRODUCTION.
Chap. 1 Structures séquentielles : listes linéaires
Chapitre VI. Arbres (définition, parcours, représentation)
Algorithmique et Structures de données
Chapitre VIII. Introduction aux graphes
Références Bibliographiques
Cours 7 - Les pointeurs, l'allocation dynamique, les listes chaînées
Structures de données linéaires
Algo-Prog en Ada TD1 2 MIC Romaric GUILLERM
IPA – Catherine Faron Zucke et Anne Marie Deryr. suite ordonnée d'éléments de taille variable ArrayList liste; liste = new ArrayList (); Ne peuvent contenir.
OCaml - Les listes L3 MI.
Chapitre V. Tables de hachage
Les éléments de base de l’algorithmique
Les structures de données arborescentes
ALGORITHMIQUE Plan du cours Généralités -définition -importance
II. Chaînage, SDD séquentielles
II. Chaînage, SDD séquentielles
Programmation fonctionnelle Le langage LISP
Algorithmique et Programmation
Structures de données IFT Abder Alikacem La classe vector Édition Septembre 2009 Département dinformatique et de génie logiciel.
Les pointeurs Modes d’adressage de variables. Définition d’un pointeur. Opérateurs de base. Opérations élémentaires. Pointeurs et tableaux. Pointeurs et.
Structures de données IFT-2000 Abder Alikacem Standard Template library Édition Septembre 2009 Département dinformatique et de génie logiciel.
Structures de données IFT-2000
Présentation Structures de Données et TDA
Les listes chaînées par Frédérick Henri.
Contrôle de types Les types en programmation Expressions de types Un contrôleur de types Equivalence de types Conversions de types Généricité.

CSI3525: Concepts des Langages de Programmation Notes # 6: Langages de Programmation Fonctionelle II: Introduction au ML.
IFT-2000: Structures de données Piles et files Dominic Genest, 2009.
1 Le fichier séquentiel Suite finie déléments dun même type Exemples : – fichier des livres dune bibliothèque – enregistrements sur un magnétophone – ensemble.
Structures de données IFT-10541
Le langage C Structures de données
Graphes 1. Introduction 2. Définition 3. Représentation mémoire
Ch. PAUL - Piles et Files à l'aide de listes chainées
LES PILES ET FILES.
INTRODUCTION.
Listes linéaires chaînées Pr ZEGOUR DJAMEL EDDINE Ecole Supérieure d’Informatique (ESI)
Chapitre 6 Les traitements avancés
Un survol du language C.
Programmation linéaire en nombres entiers
Méthodes de tri.
Chaînage et LSC : motivation et principe Manipuler la LSC : exemples Variantes : LDC, liste circulaire, … Etude de cas : réalisation d’un buffer clavier.
II. Chaînage, SDD séquentielles
ETNA – 1ème année Guillaume Belmas –
Structures simples et tableaux Pr ZEGOUR DJAMEL EDDINE Ecole Supérieure d’Informatique (ESI)
Cours LCS N°4 Présenté par Mr: LALLALI
2005/2006 Structures de Données Introduction à la complexité des algorithmes.
Pr ZEGOUR DJAMEL EDDINE Ecole Supérieure d’Informatique (ESI) C O M P I L Z.
Algorithmique Tableaux de données
 Chaînage et LSC : motivation et principe Manipuler la LSC : exemples Variantes : LDC, liste circulaire, … Etude de cas : réalisation d’un buffer clavier.
Objets et Actions Élémentaires.
Chaînage et LSC : motivation et principe Manipuler la LSC : exemples Variantes : LDC, liste circulaire, … Etude de cas : réalisation d’un buffer clavier.
L'exécution d'un programme nécessite l'utilisation des ressources de l'ordinateur : temps de calcul pour exécuter les opérations, et l'occupation de la.
ALGORITHME ET PROGRAMMATION RÉVISION Informatique et Sciences du Numérique.
Informatique 2A Langage C 5ème séance. Déroulement de la séance 5 1 ère partie Étude des chaînes de caractères 2 ème partie Les structures 3.
Transcription de la présentation:

Chapitre IV. Structures linéaires (piles, files, listes chaînées) Type de données abstrait Pile File Liste

Introduction Du problème au programme : Deux démarches : (1)descendante construire un algorithme par raffinements successifs, Représentation des données : Type de Données Abstrait, L’implémentation concrète n’est pas connue. (2)ascendante : on se donne une représentation concrète du type de données en terme d’objets du langage de programmation utilisé, ainsi que des procédures ou des fonctions correspondant aux opérations du type. (1) est plus avantageuse. En réalité, le processus de programmation est la combinaison des deux.

1.Type de données abstrait La conception d’un algorithme complexe se fait toujours en plusieurs étapes qui correspondent aux raffinements successifs. La première version de l’algorithme est autant que possible indépendante d’une implémentation particulière. En particulier la représentation des données n’est pas fixée. A ce premier niveau les données sont considérées de manière abstraite : on se donne - une notation pour les décrire; - l’ensemble des opérations qu’on peut leur appliquer; - les propriétés de ces opérations. (ex. dans plusieurs langages de programmation on manipule le type « réel » sans forcément connaître la représentation interne)

Signature d’un TDA(1) La signature d’un type de données décrit la syntaxe du type (nom des opérations, type de leurs arguments), mais elle ne définit pas les propriétés (sémantique) des opérations du type. La signature d’un type abstrait est la donnée : - de noms d’un certain nombre d’ensembles des valeurs (ex.Booléen, Entier, Liste) – « sortes » (types). La définition d’un type fait souvent intervenir plusieurs sortes -de noms d’un certain nombre d’opérations et de leurs profils; le profil précise à quels ensembles de valeurs appartiennent les arguments et le résultat d’une opération.

Signature d’un TDA(2) Type Vecteur, utilise Elément ,Entier Opérations i-ème :Vecteur x Entier->Elément changer-i-ème : Vecteur x Entier x Elément ->Vecteur bornesup : Vecteur->Entier borneinf : Vecteur->Entier Opérations : avec arguments et sans arguments. Une opération qui n’a pas d’arguments est une constante Exemple : 0 : ->Entier Vrai :->Booléen Hiérarchie des types, « sortes » prédéfinis.

Axiomes(1) Problème : donner une signification (une sémantique) aux noms de la signature : sortes et opérations; Enoncer les propriétés des opérations sous formes d’axiomes. Exemple (pour Vecteur) Axiome 1 Borneinf(v)<i<Bornesup(v)->i-ème(changer-ième(v,i,e),i)=e v,i,e sont des variables respectivement de sortes Vecteur, Entier et Elément Signification : si i est compris entre les bornes d’un vecteur v, quand on construit un nouveau vecteur en changeant le i-ème élément du vecteur v par e et ensuite on accède au i-ème élément, on obtient e Cette propriété est satisfaite quelles que soient les valeurs, de sortes convenables, données aux variables, (axiome)

Axiomes(2) Axiome (2) Borneinf(v)<i<Bornesup(v)& Borneinf(v)<j<Bornesup(v)&i!=j ->i-ème(changer-ième(v,i,e),j)=i-ème(v,j) Signification : seul le i-ème élément a changé dans le nouveau vecteur. La définition d’un TDA est donc composée d’une signature et d’un ensemble d’axiomes. Les axiomes sont accompagnés d’un certain nombre de variables. Ce type de définition s’appelle une définition algébrique ou axiomatique d’un type abstrait. Problème de consistance (pas d’axiomes contradictoires) Problème de complétude (est-ce que l’ensemble des axiomes proposé est suffisant ). Pour les types abstraits algébriques la règle de complétude est définie comme « on doit pouvoir déduire une valeur pour tous les observateurs sur tout objet d’une sorte définie appartenant au domaine de définition de cet observateur. Le domaine de définition d’une opération partielle est défini par une précondition.

Axiomes(3) Préconditions : Définissons une opération de « création » d’un vecteur vide Vect : Entier x Entier ->Vecteur Avec les axiomes Borneinf(vect(i,j))=i Bornesup(vect(i,j))=j L’opération i-ème ne peut pas être appliquée sur un vecteur pour lequel on n’a pas de valeurs d’éléments. Une nouvelle opération qui « teste » si un élément a été associé à un certain indice : Init: Vecteur x Entier -> Booléen Axiomes : Init(vect(i,j),k)=faux (borneinf(v)<i<bornesup(v)->(init(changerième(v,i,e),i)=vrai) (borneinf(v)<i<bornesup(v)&i!=j)->(init(changer-ième(v,i,e),j)=init(v,j)) Précondition sur l’opération i-ème : L’opération i-eme est définie ssi : Borneinf(v)<i<bornesup(v)&init(v,i)=vrai *exemple en c++ ( accès à l’espace –mémoire non-alloué)

Structures linéaires. Pile Piles, Files, Listes font partie des structures dynamiques linéaires. Les opérations sur un ensemble dynamique peuvent être regroupées en deux catégories : les requêtes (consultation); les opérations de modification. Les opérations classiques : rechercher(S,clé), Insertion(S,elt), Supression(S,elt), Min(S),Max(S), Successeur(S,elt), Prédécesseur(S,elt)…

Pile Pile est un ensemble dynamique dans lequel l’élément supprimé est celui le plus récemment inséré : dernier entré-premier sorti LIFO Opérations : Insérer = Empliler Supprimer = Dépiler Valeur= Recherche (toujours l’élément pointé par le sommet) Illustration graphique dans le cas d’implémentation par un tableau N S

TDA Pile Type Pile utilise Booléen, Elément Opérations Pile-vide : ->Pile {création d’une pile vide PV(P)} Empiler : Pile x Element ->Pile {EP(P,a)} Dépiler : Pile ->Pile {supprimer le dernier DP(P)} Valeur : Pile->Elément {renvoie l’élément au sommet sans modifier la pile VP(P)} Est-vide : Pile->Booléen {test si la pile est vide EV(P)} Les opérations Dépiler et Valeur ne sont définies que si la pile n’est pas vide Dépiler(P) est-défini-ssi est-vide(P)=faux Valeur(P) est-défini-ssi est –vide(P)=faux Axiomes Dépiler(Emplier(P,e))=P Valeur(empiler(P,e))=e Est-vide(Pile-vide)=vrai Est-vide(Empiler(P,e))=faux

Evaluation d’une expression A l’aide des opérations et des axiomes du TDA Pile évaluer l’expression suivante : EV(DP(DP(EP(EP(PV,a)),b)))?

Pile. Implémentation à l’aide d’un tableau(1) Type Pile = enregistrement sommet : entier; elts : tabelau [1..lmax] d’Element FinEnregistrement Procédure Pile-vide(réf P: Pile) Début P.sommet:=0; Fin Pile-vide; Procédure Empiler(réf P: Pile, val X : Elément); Procédure Dépiler(réf P: Pile); Fonction Valeur(val P: Pile) : Elément; Fonction Est-vide(val P: Pile) : Booléen;

Pile. Implémentation à l’aide d’un tableau(2) Procédure Empiler(réf P: Pile, val X : Elément) Début Si P.sommet=lmax Alors Erreur « débordement » Sinon P.sommet:=P.sommet+1; P.elts[P.sommet]:=X; FinSiFinEmpiler Remarque : chacune des opérations (Empiler, Dépiler) consomme le temps en O(1) Problème: Expliquer comment implémenter deux piles dans un tableau A[1..n] de telle manière qu’aucune ne déborde à moins que le nombre total d’éléments des deux piles vaille n. Les opérations Empiler et Dépiler devront s’exécuter dans un temps en O(1)

TDA File(1) Dans le cas d’une file on fait les adjonctions à une extrémité, les accès et les suppressions à l’autre extrémité. Les files sont aussi appelées FIFO ( first –in –first out) : premier-entré-premier-sorti Une file comporte une tête et une queue. Les éléments sont donc retirés et consultés dans la tête et rajoutés dans la queue T Q

TDA File(2) Type File utilise Booléen, Elément Opérations File-vide : ->File {création d’une file vide FV(F)} Enfiler : File x Elément ->File {EF(F,a)} Défiler : File ->File {supprimer le dernier DF(F)} Valeur : File->Elément {renvoie l’élément au sommet sans modifier la file VF(F)} Est-vide : File->Booléen {test si la file est vide EV(F)} Les opérations Défiler et Valeur ne sont définies que si la file n’est pas vide Défiler(F) est-défini-ssi est-vide(F)=faux Valeur(F) est-défini-ssi est –vide(F)=faux Axiomes Est-vide(F)=vrai => Valeur(Enfiler(F,e))=e Est-vide(F)=faux => Valeur(Enfiler(F,e))=Valeur(F) Est-vide(F)=vrai => Défiler(Enfiler(F,e))= File-vide Est-vide(F)=faux => Défiler(Enfiler(F,e))=Enfiler(Défiler(F),e) Est-vide(File-vide)=vrai Est-vide(Enfiler(F,e))=faux

Représentation contiguë des files Moyens de représentation : tableau i<j i j Lmax-1 i>j j i Lmax-1 i=j Lmax-1 File vide i=j Lmax-1 File pleine ? On fait progresser les indices modulo taille Lmax du tableau

Représentation contiguë des files(2) Gérer les débordements (1) Enfiler j:=j+1 mod lmax Si j=i alors File-pleine sinon Si File-vide(F) alors i:=j; FSi Tab[j]:=e; FSI (2) Défiler Si !File-vide(F) i:=i+1 mod lmax e:=Tab[i]; Si i:=j alors j:=-1; i:=-1; FSi (3) File vide  i=-1et j=-1

Listes chaînées(1) Une liste chaînée est une structure de données dans laquelle les objets sont arrangés successivement … nil élément pointeur maillon Liste=pointeur …

Listes chaînées(2) Type Liste = ^Maillon; Type Maillon = Enregistrement Elt : Elément; Suivant : Liste Fin; Déclaration d’une liste : L : Liste

Listes Listes contigües : ex. tableau des entiers = liste contigüe des entiers Listes chaînées : adressage à l’aide de « Suivant » Définition récursive :

Listes Exemple (8,5,6,7,4,8) L:=<8,L1> L1:=<5,L2>

TDA Liste(1) Opérations ListeVide? : Liste ->Booléen Tête : Liste->^Maillon Valeur : ^Maillon->Elément Successeur : ^Maillon->^Maillon EstDernier? : ^Maillon ->Booléen Longueur : Liste ->Entier Primitives dynamiques CréerListe : -> Liste Insérer Ième : Liste X Entier X Elément -> Liste Supprimer Ième : Liste X Entier ->Liste Insérer en Tête : Liste X Elément -> Liste Supprimer en Tête : Liste -> Liste

TDA Liste(3) D’autres opérations Exemple : L=(A,B,C) Ième : Liste X Entier ->Elément Premier : Liste -> Elément Fin : Liste ->Liste Exemple : L=(A,B,C) Premier(L)=A Fin(L)=(B,C) Insérer en Tête(L,D)=(D,A,B,C)

TDA Liste (2) Quelques axiomes : L≠Liste-Vide=>Premier(L)=Valeur(Tête(L)) Fin(Insérer en Tête(L, E))=L L≠Liste-Vide=>Successeur(Tête(L))= Tête(Fin(L))

Recherche dans une liste chaînée Recherche : Liste X Elément ->^Maillon Fonction Recherche(val L: Liste, E: Elément): Liste Var PX : Liste; Début PX:=Tête(L); Tant que PX ≠ nil et PX^.Elt ≠E faire PX:=Successeur(PX); FTq Retourner PX; Fin Recherche

Insertion dans une liste chaînée Fonction InsérerenTête(ref L: Liste, val E: Elément) : Liste Var Tampon : Liste; new(Tampon);{allocation de mémoire) Début Tampon^.elt:=E; Tampon^.suivant:=Tête(L); L:=Tampon; Retourner L; Fin InserérenTête

Suppression dans une liste chaînée Supprimer Ième: Liste X Entier -> Liste Procédure SupprimerIème(ref L:Liste, val i: entier, ref erreur booléen); Var P, PP : Liste; Debut Si L = nil alors erreur:=vrai; sinon Si i=1 alors L:=Successeur(L); erreur:=faux; P:=Tête(L); k:=1; Tant que P ≠ nil et k < i-1 PP:=P; P:=P^.suivant; k:=k+1; FTq Si P ≠ nil PP^.suivant=Successeur(P); FSi FinSupprimerIème