Types de données abstraites

Slides:



Advertisements
Présentations similaires
GEF 243B Programmation informatique appliquée Listes chaînées I – Tableaux de structures §15.1 – 15.2.
Advertisements

Tris.
Portée des variables VBA & Excel
Structures de données et complexité
Structures de données et complexité LIFO – FILO – FIFO – etc…
INTRODUCTION.
Chap. 1 Structures séquentielles : listes linéaires
8. Les tableaux P. Costamagna – ISEN N1.
Les sous-programmes Chapitre n° 5: Objectifs : Activité:
Initiation à la programmation et algorithmique cours 3
Chapitre IV. Structures linéaires (piles, files, listes chaînées)
Cours 7 - Les pointeurs, l'allocation dynamique, les listes chaînées
Structures de données linéaires
Algorithmique et Programmation
Les structures de données arborescentes
II. Chaînage, SDD séquentielles
Initiation à la conception de systèmes d'information
Leçon 6 : Structures de données dynamiques IUP 2 Génie Informatique Méthode et Outils pour la Programmation Françoise Greffier.
8PRO100 Éléments de programmation Allocation dynamique de la mémoire.
II. Chaînage, SDD séquentielles
Programmation fonctionnelle Le langage LISP
IFT-2000: Structures de Données Listes chaînées Dominic Genest, 2009.
Algorithmique et Programmation
FICHIERS : Définition : Algorithme général:
Les fichiers indexés (Les B-arbres)
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.
Présentation Structures de Données et TDA
Semaine #1 INF135 par Frédérick Henri.
Gestion de Fichiers Tri Interne Efficace et Tri Externe.
8PRO100 Éléments de programmation Les types composés.
Partie II Sémantique.
Méthode et Outils pour la Programmation
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
Plan cours La notion de pointeur et d’adresse mémoire.
Structures de données IFT-2000 Abder Alikacem La récursivité Département d’informatique et de génie logiciel Édition Septembre 2009.
Types de données fondamentaux
Le langage C Structures de données
Graphes 1. Introduction 2. Définition 3. Représentation mémoire
Le langage C Rappel Pointeurs & Allocation de mémoire.
LES PILES ET FILES.
Les Pointeurs et les Tableaux Statiques et Tableaux Dynamiques
INTRODUCTION.
PROGRAMMATION INFORMATIQUE D’INGÉNIERIE II
Un survol du language C.
Programmation linéaire en nombres entiers
1 Structures des données. 2  Le tableau permettait de désigner sous un seul nom un ensemble de valeurs de même type, chacune d'entre elles étant repérée.
II. Chaînage, SDD séquentielles
Le langage Racket (Lisp)
ETNA – 1ème année Guillaume Belmas –
Structures simples et tableaux Pr ZEGOUR DJAMEL EDDINE Ecole Supérieure d’Informatique (ESI)
CSI 3525, Implémentation des sous-programmes, page 1 Implémentation des sous-programmes L’environnement dans les langages structurés en bloc La structure.
CHAPITRE III Calcul vectoriel
Cours LCS N°4 Présenté par Mr: LALLALI
CPI/BTS 2 Algorithmique & Programmation La récursivité Algo – Prog CPI/BTS2 – M. Dravet – 14/09/2003 Dernière modification: 14/09/2003.
8PRO107 Éléments de programmation Les adresses et les pointeurs.
Scripts et fonctions Instructions de contrôle
Une aide pour débutant éclairé
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.
Organisation de la mémoire pour le langage minimal Pr ZEGOUR DJAMEL EDDINE Ecole Supérieure d’Informatique (ESI)
Algorithmique Boucles et Itérations
Chap. 3 Récursion et induction. Les définitions par récurrence consistent à construire des objets finis, à partir d'autres, selon certaines règles. Les.
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.
L ES INSTRUCTIONS DE L ECTURE, E CRITURE ET A FFECTATION Réalisé par : OUZEGGANE Redouane Département de Technologie Faculté de Technologie – Université.
1 Initiation aux bases de données et à la programmation événementielle VBA sous ACCESS Cours N° 4 Support de cours rédigé par Bernard COFFIN Université.
Transcription de la présentation:

Types de données abstraites Algorithmique Types de données abstraites Somaya EL GHARRAS

L’informatique consiste en un traitement automatique de l’information. Somaya EL GHARRAS

Les concepts fondamentaux : 1er concept : Pour pouvoir être traitée automatiquement, l’information doit être formalisée, modélisée sous forme d’un ensemble structuré de relations logicomathématiques : « formalisation et modélisation de l’information ». 2ème concept : Il a trait au « système » qui va effectuer automatiquement le traitement de l’information. Ce concept est celui « d’architecture des systèmes de traitement automatique de l’information ». Somaya EL GHARRAS

Les concepts opérationnels A partir de ces deux concepts fondamentaux, ont été élaborés d’autres concepts dits opérationnels tels que : Algorithme Programme Structure de données Somaya EL GHARRAS

Structures de données Le type d’une variable : L’ensemble des valeurs qu’une variable peut prendre est appelé son type. Le type attribué aux différentes constantes, variables ou fonctions est rendu explicite dans une déclaration. Une déclaration de variable est notée : Var v : T Somaya EL GHARRAS

Les types structurés Les données simples, par exemple un entier ou un réel, ne sont par nécessairement considérés isolément mais peuvent être regroupés en un tout complexe formant une donnée structurée. L’exemple le plus largement connu est sans doute le tableau de valeurs d’un même type et la plupart des langages offrent des facilités pour introduire de tels tableaux. Somaya EL GHARRAS

Enregistrement   Il est courant et utile de structurer dans une même structure des données de types différents. Somaya EL GHARRAS

Type date = enregistrement jour : 1..31 ; mois : 1..12 ; année : 1900 ..2009 ; fin ; alpha = chaîne de caractère (20) ; sex = (homme, femme) ; personne = enregistrement nom : alpha ; prénom : alpha ; naissance : date ; sexe : sex ; var p : personne ; Somaya EL GHARRAS

Le mois de sa naissance est sélectionné par : p.naissance.mois Le prénom de la personne enregistrée dans la variable p est sélectionné par : p.prénom Le mois de sa naissance est sélectionné par : p.naissance.mois Somaya EL GHARRAS

Soit a un tableau de 50 personnes.   Var a : tableau [1..50] de personne ; Le prénom de la personne enregistrée au rang i est sélectionné par : a[i].prénom Son mois de naissance est sélectionné par : a[i].naissance.mois Somaya EL GHARRAS

Enregistrement à format variable Il est utile de définir dans un même type des enregistrements dont la structure peut varier en fonction du cas rencontré. On utilise à cette fin un indicateur de cas. Somaya EL GHARRAS

Ex 1  les coordonnées d’un point du plan peuvent être données soit en cartésienne soit en polaire. Type coordonnée = enregistrement Cas sorte : (cartésien, polaire) de Cartésien : ( x, y : réel) ; Polaire : (r : réel, a: angle) ; Fin ; Somaya EL GHARRAS

L’indicateur de cas est ‘sorte’ qui est du type (cartésien, polaire) L’indicateur de cas est ‘sorte’ qui est du type (cartésien, polaire). Selon la valeur de cet indicateur les composantes suivantes de l’enregistrement sont deux réels x et y, ou, un réel r et un angle a où l’on suppose que le type angle a été défini préalablement. Somaya EL GHARRAS

Type T = enregistrement Si l’indicateur de cas est une valeur logique, la déclaration peut prendre la forme suivante :  Type T = enregistrement s1 : T1 ; s2 : T2 ; … ; sn-1 : Tn-1 ; si t alors (s1,1 : T1,1 ; … ; s1,n1 : T1,n1) sinon (s2,1 : T2,1 ; … ; s2,n2 : T2,n2) Fin; Somaya EL GHARRAS

Ex2 Le type coordonnée peut être défini en utilisant une variable logique ‘cart’ au lieu de ‘sorte’, en supposant ‘cart’ vrai s’il s’agit de coordonnées cartésiennes et faux sinon.  Type coordonnée = enregistrement Si cart alors (x,y : réel) sinon (r : réel ; a :angle) fin ; Somaya EL GHARRAS

Type de données abstraites On peut concevoir un type de données abstraites comme la connaissance d’un modèle mathématique et des opérations qui lui sont associées. Somaya EL GHARRAS

Structures de données dynamiques Considérons, par exemple, la généalogie d’une personne connue ou inconnue définie par : La mention « inconnu » pour un individu qui ne l’est pas ; La mention « connu » suivi de son « nom » et de la généalogie du père » et de « celle de la mère », pour une personne connue. Somaya EL GHARRAS

Pour répondre à ce genre de situation, on a recours à une allocation dynamique de la mémoire, c’est-à-dire que la réservation de l’espace nécessaire se fait au moment de l’exécution au fur et à mesure des besoins rencontrés. Ceci par opposition à une allocation statique pour laquelle la réservation peut être faite avant l’exécution. Les structures de données qui supposent une allocation dynamique sont appelées des structures dynamiques. Somaya EL GHARRAS

Données récursives  Considérons la généalogie d’une personne mentionnée précédemment. Type généalogie = enregistrement Si connu alors (nom : alpha ; père, mère : généalogie) fin ; Somaya EL GHARRAS

La valeur du type généalogie définie par : (V, Mohammed, (V, Ali, (V, Brahim, (F), (F)), (F)), (V, Fatima, (F), (V, Aicha, (F), (F)))) est représentée par la figure suivante. V et F se lisent vrai et faux, chaque paire de parenthèses associées se lit comme la construction d’une valeur du type : généalogie ( ). Somaya EL GHARRAS

V Mohammed V Ali V Brahim F F F V Fatima F V Aicha F F

Exemple 2 Une « expression » consiste en : un terme suivi d’un opérateur suivi d’un terme. Les deux termes sont les opérandes de l’opérateur qu’ils encadrent. Un terme est soit une variable – représentée par un identificateur – soit une expression entre parenthèses.

expression = enregistrement op1, op2 : terme ; fin ; Type expression = enregistrement Op : opérateur ; op1, op2 : terme ; fin ; terme = enregistrement si t alors (id : alpha) sinon (sousexp : expression)

Les expressions suivantes : x + y x - (y * z) (x + y) * (z - u) (x / (y + z)) * u peuvent être représentées par les figures suivantes :

Le type pointeur Considérons la figure qui représente sous une autre forme la généalogie de la figure précédente. L’indicateur Vrai ou Faux y est présent ainsi que le nom, mais l’emboîtement des généalogies y est figurée par deux flèches ou pointeurs qui renvoient respectivement à la généalogie du père pour la plus à gauche, à la généalogie de la mère pour la plus à droite. Figure

Si nous supprimons la généalogie d’une personne inconnue, nous pouvons du même coup nous passer de l’indicateur. Certaines flèches, dans un tel cas, « ne vont nulle part ». Nous pouvons le noter au moyen d’une flèche spéciale que nous appellerons nil (null). figure

Supposons qu’après avoir établi la généalogie de Mohammed, nous découvrons dans une étape ultérieure que la mère de Ali est Zahra dont la généalogie nous est donnée par la figure suivante Ces considérations suffisent à justifier l’introduction d’un type de données, pointeur, qui répond au fonctionnement des flèches.

Un pointeur est une variable contenant l'adresse d'une autre variable d'un type donné. Cette technique de programmation très puissante, permet de définir des structures dynamiques, c'est-à-dire qui évoluent au cours du temps (par opposition aux tableaux par exemple qui sont des structures de données statiques, dont la taille est figée à la définition).

Un type de pointeur est défini par une déclaration de la forme : Type Tp = ^T Où la flèche verticale se lit « pointeur vers » et T est un type préalablement défini. Langage C : Etant donné un type T quelconque, le type pointeur sur T s'écrit « T* » Ainsi, la définition d'une variable p du type ««pointeur sur T » correspond à l'instruction           T *p;

La valeur spéciale nil (null), mentionnée plus haut pour figurer la « flèche qui ne va nulle part », est une valeur possible de tout pointeur p indépendamment de son type. Elle lui est affectée par p := nil.

Hormis ce cas spécial, la valeur d’un pointeur p de type ^T est une variable de type T. Cette variable est notée p^. Cependant, p^ n’est pas entièrement assimilable à un identificateur de variable du type T. En effet, on ne suppose pas a priori qu’un espace est réservé pour ranger la valeur de p^. La réservation d’un tel espace est dynamique. Elle est explicitement demandée par l’instruction : Nouveau (p) ;

Deux pointeurs p et q du même type ^T peuvent viser la même variable de type T. C’est le cas après une affectation de la forme q := p Figure

L’espace alloué à un instant donné à la variable visée par un pointeur peut se trouver libéré lors de l’exécution d’une instruction de la forme : Nouveau(p) ou p := q

Après l’exécution de la suite d’instructions : Nouveau (p) ; q := p ; nouveau(p) L’espace initialement réservé pour p^ reste réservé pour q^ (figure 2.5.d)

Pour le reste, notamment lors des affectations de valeurs, l’identificateur p^ associé à un pointeur p du type ^T joue le rôle d’un identificateur de variable du type T. On doit retenir que si un autre pointeur q du type ^T pointe vers la même variable que p (figure 2.5.c) toute modification de la valeur de p^ est une modification de la valeur de q^.

Représentation en mémoire des pointeurs L’instruction nouveau(p), où p est un pointeur de type ^T, a pour effet de réserver l’allocation mémoire pour une variable de type T avec p pointant sur cette variable. Figure

Structures fondamentales Les structures fondamentales de base : tableau, enregistrement, pointeur ont été définies comme des types de données. D’autres structures : listes linéaires, arbres, …, jouent un rôle important. Mais il n’est pas nécessaire pour les définir d’introduire des types d’un caractère entièrement nouveau.

Notion de suite (ou liste) Dans la vie courante, on a souvent affaire à des collections homogènes d’objets ou d’individus, dont la taille est susceptible de varier à la suite d’ajouts ou de retraits d’éléments, organisées de la manière suivante : On sait repérer l’une, l’autre ou les deux extrémités de la structure ; Les éléments sont ordonnés, et l’on peut donc définir le suivant et le précédent de tout élément qui n’est pas une extrémité ; Pour atteindre un élément particulier, on doit nécessairement parcourir séquentiellement la structure à partir d’une extrémité, jusqu’à le trouver.

Nous appelons suite une telle organisation dynamique homogène Nous appelons suite une telle organisation dynamique homogène. Selon le mode d’exploitation d’une suite, on définit différentes structures de données que nous allons présenter. La notion de liste linéaire est celle d’une suite finie d’éléments qui est donnée par un premier élément, et pour chaque élément un lien donnant accès à son suivant.

D’un point de vue mathématique, une liste est une suite, vide ou non d’éléments d’un type donné (que nous désignerons par TypeElement). Il est habituel de représenter une telle suite par : a1, a2, …, an Où n est positif, et où chaque ai est de type TypeElement. Le nombre n d’éléments s’appelle la longueur de la liste. Si n>= 1, on dit que a1 est le premier élément et an le dernier. Si n = 0, on parle de liste vide, sans éléments.

Pour construire un type de données abstraites à partir de la notion mathématique de liste, il nous faut définir un ensemble d’opérations sur des objets de type LISTE.

Mise en œuvre des listes Mise en œuvre des listes par tableau Une telle mise en œuvre, où les éléments des listes sont mémorisés dans les cellules contiguës d’un tableau, facilite le parcours de listes et l’insertion d’éléments en fin de liste (nous dirons souvent « en queue »).

En revanche, l’insertion d’un élément au milieu d’une liste nécessite de déplacer tous les éléments suivants dans le tableau pour créer la place nécessaire au nouveau venu. De même, la suppression d’un élément quelconque du tableau demande que l’on déplace tous ses successeurs pour « boucher le trou » produit, sauf s’il s’agit du dernier élément de la liste. Figure

LISTE = enregistrement Const Longmax = 100 ; {ou n’importe quelle constante appropriée} Type LISTE = enregistrement Elements : tableau [1.. longmax] de TypeElement ; Dernier : entier ; Fin ; Position = entier ; Fonction Fin (var L : LISTE) : position ; Début Retourne ( L.dernier + 1)

Mise en œuvre des listes par pointeurs Une liste est un ensemble de cellules « simplement chaînées » Grâce à cette mise en œuvre nous n’aurons plus à faire de la place ou combler de vide pour insérer ou supprimer des éléments dans les listes, puisque nous n’utiliserons plus comme zone de stockage un ensemble de cellules contiguës de la mémoire de la machine.

Dans cette représentation, une liste est constituée de cellules, chacune étant composée d’un élément de la liste et d’un pointeur sur la cellule suivante.

Si la liste est composée de la suite a1, a2, …, an, la cellule contenant ai pointe sur celle contenant ai+1, pour i = 1, 2, …, n-1. La cellule contenant an pointe sur nil. Il existe aussi une cellule de tête, appelée en_tête, qui pointe sur a1 ; en_tête ne contient pas d’élément. Dans le cas d’une liste vide, en_tête pointe sur nil et la structure ne contient pas d’autre cellule. Figure

Pour les listes simplement chaînées, il est habituel d’utiliser une définition du type position quelque peu différente de celle que nous avons donné dans la mise en œuvre par tableau. Ici, la position i est un pointeur sur la cellule contenant un pointeur sur ai pour i = 2, 3, …, n. La position 1 est un pointeur sur l’en-tête, et la position FIN(L) est un pointeur sur la dernière cellule de L.

Type Typecellule = enregistrement Element : typeElement ; Suivant : ^typecellule ; Fin ; LISTE = ^typecellule ; Position = ^typecellule ;

Fonction FIN (L : LISTE) : position {FIN retourne un pointeur sur la dernière cellule de L} var q : position début q := L ; tant que q^.suivant <> nil faire q := q^.suivant ; retourne (q) ; fin ;

Remarquons que cette mise en ouvre n’est pas judicieuse car elle oblige à parcourir la liste en entier chaque fois que l’on désire connaître FIN (L). Nous pourrions représenter les listes en incluant un pointeur sur la dernière cellule.

Procédure d’insertion d’un élément dans une liste représentée par tableau  Procédure Insérer (x : TypeElement ; p : position ; var L : LISTE) ; {insérer x à la position p dans la liste L} var q : position ; début Si L.dernier >= longmax alors écrire « la liste est pleine » Sinon Si (p > L.dernier +1) ou (p < 1) Alors écrire « position non valide » Sinon Début Pour q := L.dernier downto p faire {décaler les éléments aux positions p, p+1,.. d’un rang vers la fin de L} L.elements [q+1] := L.elements [q] ; L.dernier := L.dernier + 1 ; L.elements [p] := x Fin ; Fin ; {insérer}

Les piles Une pile est un type de liste particulier dans lequel toute insertion ou suppression d’élément se fait à une extrémité, appelée dessus ou sommet de la pile. les seules actions possibles sont l’ajout (empilement) ou le retrait (dépilement) d’un élément au sommet.

Un type de données abstraites de la famille des piles comprend souvent les cinq opérations suivantes : RAZ (P) : vider le contenu de la pile P. Cette opération est identique à l’opération correspondante pour les listes en général. SOMMET (P) : retourner (sans le dépiler) l’élément au sommet de la pile P. DEPILER (P) : supprimer physiquement l’élément au sommet de la pile P. EMPILER (x, P) : insérer l’élément x au sommet de la pile P. L’ancien élément le plus haut devient le deuxième et ainsi de suite. VIDE (P) : cette fonction retourne VRAI si P est vide et FAUX sinon.

L’implantation par pointeurs d’une pile est facilitée par le fait que EMPILER et DEPILER n’opèrent que sur la tête de liste et la première cellule de la liste. En fait les têtes de listes peuvent être des pointeurs (ou des curseurs), et on plus des cellules à part entière, puisque la notion de « position » est inutile pour les piles. Un curseur (ou un pointeur) appelé sommet indique la position à tout instant du premier élément de la pile. Figure

Remarquez que si sommet = longmax + 1, la pile est vide. Type PILE = enregistrement Sommet : 1..longmax ; Elements : tableau [1 .. longmax] de TypeElement Fin ; Une variable de type PILE sera donc entièrement déterminée par la donnée de la suite elements [sommet] , elements[sommet + 1], … , elements [longmax]. Remarquez que si sommet = longmax + 1, la pile est vide.

Procédures et fonctions sur les piles Procédure RAZ (var P : PILE) ; Début P.sommet := longmax +1 Fin ; Fonction VIDE (P : PILE) : booléen ; Si P.sommet > longmax alors retourne (VRAI) Sinon retourne (FAUX)

Fonction SOMMET (var P : PILE) : TypeElement ; Début Si VIDE(P) alors écrire (‘la pile est vide’) Sinon retourne (P.elements [P.sommet]) Fin ;

Procédure DEPILER (var P : PILE) ; Début Si VIDE(P) alors écrire (‘la pile est vide’) Sinon P.sommet := P.sommet + 1 Fin ; Procédure EMPILER (x : TypeElement ; var P : PILE) ; Si P.sommet = 1 alors écrire (‘la pile est pleine’) Sinon P.sommet := P.sommet – 1 P.elements [P.sommet] := x

Les files Une file est un autre type particulier de liste où les éléments sont insérés en queue et supprimés en tête. les insertions se font en fin de liste plutôt qu’en début.

Opérations sur les files RAZ (F) : transforme F en file vide. TETE (F) : fonction qui retourne l’élément en tête de la file F. ENFILER (x,F) : insère l’élément x à la fin de la file F. DEFILER (F) : supprime le premier élément de la file F. VIDE (F) : fonction booléenne qui retourne VRAI si la file F est vide et FAUX sinon.

Mise en œuvre des files par pointeurs Type TypeCellule = enregistrement Element : TypeElement ; Suivant : ^TypeCellule Fin ;

Nous pouvons ensuite définir une file comme la donnée de deux pointeurs : un premier sur la tête de liste et un second sur la queue.

Type FILE = enregistrement Tete, queue : ^TypeCellule Fin ;

Opérations sur les files Procédure RAZ (var F : FILE) ; Début Nouveau (F.tete) ; {création d’une cellule de tête} F.tete^.suivant := nil ; F.queue := F.tete ; {l’en-tête est à la fois la dernière et la première cellule} Fin ; Fonction VIDE (F : FILE) : booléen ; Si F.tete = F.queue alors retourne (VRAI) Sinon retourne (FAUX) Fonction TETE (F : PILE) : TypeElement ; Si VIDE(F) alors écrire (‘la file est vide’) Sinon retourne (F.tete^.suivant^.elements)

Procédure DEFILER (var F : FILE) ; Début Si VIDE(F) alors écrire (‘la File est vide’) Sinon F.tete := F.tete^.suivant Fin ; Procédure ENFILER (x : TypeElement ; var F : FILE) ; Nouveau (F.queue^.suivant) ; {ajouter une nouvelle cellule en queue de file} F.queue  := F.queue^.suivant ; F.queue^.element := x ; F.queue^.suivant := nil