Académique Documents
Professionnel Documents
Culture Documents
Données
– Cours –
Chapitre 03 : Structures de données linéaires : Liste, Pile et
File
Partie01: Introduction aux Types Abstraits de Données (TAD)
Staff pédagogique
Nom Grade Faculté/Institut Adresse e-mail
BELALA Faiza Professeur Nouvelles Technologies Faiza.belala@univ-constantine2.dz
HAMMOUD Djamila MCB Nouvelles Technologies Djamila.hammoud@univ-
constantine2.dz
Etudiants concernés
Faculté/Institut Département Année Spécialité
Nouvelles Technologies MI Licence 2
Objectifs du cours
Objectif 1: Cette première partie du cours permet d'initier les étudiants au concept de type Abstrait
de Données, à quoi il sert ? comment s'en servir? pourquoi recourir au TAD dans l'élaboration des
algorithmes.
1. Introduction
1.1. Structures de données: Moyen pour stocker et organiser les données pour en faciliter l’accès et
la modification.
1.2. Type Abstrait de Données (TAD): c’est un moyen de définition ou spécification de données, il
spécifie précisément :
la nature et les propriétés des données
les modalités d’utilisation des opérations pouvant être effectuées
indépedement de toute représentation interne de ces données ainsi que la mise en oeuvre des
opérations.
En général, un TAD admet différentes implémentations (plusieurs représentations possibles des
données, plusieurs algorithmes pour les opérations).
Les trois premières notions définissent la signature d’un TAD, les propriétés sont exprimées
généralement sous forme d’axiomes dans un TAD
2.1 Signature
Les sortes ne sont rien d’autre que des noms servant à représenter des ensembles de valeurs sur
lesquels vont porter les opérations. Par exemple naturel, booleen, entier, etc.
Chaque opération est définie par son profil : les sortes de ses paramètres et la sorte du résultat. La
forme générale du profil d’une opérations n-aire est:
Nom-opération : sorte1, sorte2, ..., sorten → sorter.
Exemples de signature: Les signatures suivantes sont extraites des TADs BOOLEEN et
NATUREL:
TAD BOOLEEN TAD NATUREL
Sorte booléen Sorte nat
Opérations Opérations
vrai : → booléen 0 : → nat
faux : → booléen succ : nat → nat
_ et _ : booléen, booléen → booléen _ + _ : nat , nat → nat
_ ou _ : booléen, booléen → booléen _ - _ : nat , nat → nat
non_: booléen → booléen _ * _ : nat , nat → nat
_ ^_ : nat , nat → nat
La signature sert à définir les régles d'écriture des données. Par exemple, à l'aide des signatures
précédentes, nous pouvons affirmer ou non que les données suivantes sont correctes
syntaxiquement.
Remarque:
Plusieurs notations peuvent être utilisées pour représenter les données à l'aide des opérations d'une
signature:
notation mixfixée, les arguments sont situées de part et d'autre du nom de l'opération (_+_,
_*_, _et_, ...), le "_" désigne la position de l'argument.
notation infixée, les arguments sont situées avant le nom de l'opération,
notation préfixée, les arguments sont situées après le nom de l'opération (succ, non, ...), dans
ce cas, nous utilisons généralement les parenthèses pour les séparer du nom de l'opération
.
2.2 Réutilisation d'un TAD
Dans une signature, on appelle sorte(s) définie(s) la ou les sortes correspondant aux noms de sortes
nouveaux.
On appelle sorte(s) prédéfinie(s) la ou les sortes provenant des TADs utilisés.
Une opération est dite interne constructeur si elle rend un résultat d’une sorte définie. Ces
opérations servent à construire les valeurs d’une sorte. Par exemple, l’opération ”succ” dans le TAD
NATUREL, permet de construire tous les entiers.
Une opération est dite interne non constructeur si elle rend un résultat d’une sorte définie mais ne
construit pas de nouvelles valeurs pour cette sorte. Par exemple, l’opération ”_+_” dans le TAD
NATUREL.
Enfin, une opération est dite observateur sur une sorte définie si elle rend un résultat d’une sorte
prédéfinie et possède au moins un argument de sorte définie. Par exemple, l’opération ”_=_” dans le
TAD NATUREL1 ci dessous,
TAD NATUREL1
Utilise BOOLEEN
Sorte nat
Opérations
0 : → nat
succ : nat → nat Internes constructeurs
Les proprétés des opérations définies dans un TAD sont données sous formes d'axiomes. Les
axiomes servent souvent à donner une signification (une sémantique) aux sortes et opérations de la
signature. La forme générale de l’écriture des axiomes est:
termegauche ≡ termedroit
Le symbole ”≡” doit se lire comme est ”équivalent en sens à”, il n’a pas de direction privilégiée.
Cette forme peut s’étendre à l’expression des axiomes conditionnels comme suit:
termegauche ≡ si condition alors termedroit1 sinon termedroit2
Exemples d’axiomes
Si on veut complèter le TAD NATUREL par des axiomes, Il faut écrire pour chaque opération
observateur ou interne non constructeur (_+_, _-_, etc.), autant d’axiomes que d’opérations internes
constructeurs (0 et succ) combinées avec les arguments associés, c.-à-d. quatre axiomes pour
l’opération _+_.
0 + 0 ≡ 0;
0 + succ(Y) ≡ succ(Y);
succ( X) + 0 ≡ succ(X);
succ(X) + succ(Y) ≡ succ(X + succ(Y));
qui sont combinés deux à deux pour donner les axiomes 1 et 2 suivants.
Axiomes
1- X + 0 ≡ X;
2- X + succ(Y) ≡ succ(X + Y);
Etant données d1, d2, d3, d4 des valeurs de données du TAD NATUREL (ci dessus), sachant que:
d1= succ(0)+succ(succ(0)),
d2=succ(succ(0,0)),
d3=succ(succ(0))+1,
d4=succ(succ(succ(0))),
D'une part, on peut vérifier aisément que seules d1 et d4 sont correctes syntaxiquement par rapport
à la signature du TAD NATUREL présentée précedemment.
Dans d2, l’opération succ est utilisée avec deux arguments au lieu d’un seul, la donnée d3 utilise un
terme “1” qui n’est pas spécifié dans la signature correspondante.
D'autre part et selon ces deux axiomes, on peut déduire que la donnée d1 a le même sens que d4,
malgré qu’elles sont écrites différemment. On applique l’axiome 2, deux fois de suite à la donnée
d1, suivi de l’application de l’axiome 1, on retrouve d4. L'application d'un axiome consiste à
instantier la donnée en question avec son terme gauche, faire les substitutions nécessaires des
différentes variables, et remplacer alors cette donnée par son équivalent défini par le terme droit de
l'axiome.
Remarques:
1. Nous tenons à remarquer que les axiomes données pour exprimer la sémantique de
l'opération _-_ du TAD NATUREL peuvent être changés et simplifiés en insérant une clause
précondition dans le TAD en question, afin de restreindre (limiter) le domaine de définition
des arguments de cette opération. Il s'agit de définir cette opération: x-y uniquement pour x
≥ y. La précondition d'une opération s'écrit ainsi:
Précondition
x-y définie ssi x ≥ y
Axiomes
...
X - 0 ≡ X;
succ(X) - succ(Y) ≡ X - Y;
...
2. Nous résumons dans ce qui suit les TAD NATUREL et BOOLEEN qui décrivent les données de type entiers positifs et les
données booléennes.
TAD NATUREL
TAD BOOLEEN Sorte nat
Sorte booléen Opérations
Opérations 0 : → nat
vrai : → booléen succ : nat → nat
faux : → booléen _ + _ : nat , nat → nat
_ et _ : booléen, booléen → booléen _ - _ : nat , nat → nat
_ ou _ : booléen, booléen → booléen _ * _ : nat , nat → nat
non_: booléen → booléen _ ^_ : nat , nat → nat (puissance)
Variables b: booléen Variables X, Y : nat
Axiomes Précondition
1- non vrai ≡ faux; X-Y définie ssi X Y (convention pour éviter de
2- non faux ≡ vrai; sortir des entiers naturels)
3- vrai et b ≡ b; Axiomes
4- faux et b ≡ faux; 1- X + 0 ≡ X;
5- vrai ou b ≡ vrai; 2- X + succ(Y) ≡ succ(X + Y);
6- faux ou b ≡ b; 3- 0 - X ≡ 0;
4- X - 0 ≡ X;
5- succ(X) - succ(Y) ≡ X - Y;
6- X * 0 ≡ 0;
7- X * succ(Y) ≡ X + (X * Y);
8- X ^0 ≡ succ(0);
9- X ^succ(Y) ≡ X * (X ^Y);
Nous notons l'intérêt de spécifier (décrire) les structures de données utilisées dans un algorithme
avec un TAD à travers l'exemple ci dessous. Nous montrons comment passer d'une telle
définition à son implémentation ou sa représentation au niveau d'un programme en utilisant
n'importe quel langage de programmation.
Exemple
Nous considérons la structure de données "complexe" qui organise les données de type
"nombres complexes". Le TAD correspondant peut être donné par:
TAD COMPLEXE
Utilise REEL
Sorte complexe
Opérations
constC : réel, réel → complexe Interne constructeur
rl : complexe → réel
im : complexe → réel
module: complexe réel Observateurs
La même remarque est aussi valable pour ces deux derniers axiomes, qui seront écrits ainsi:
Variables
r1, r2, r3, r4 : réel, z, z1, z2 : complexe
Ainsi, si nous voulons implémenter le TAD complexe, il suffit d'associer une représetation interne aux
différentes données de sorte complexe, un enregistrement par exemple (on peut aussi choisir un tableau à deux
éléments), et une implémentation adéquate des différentes opérations définies.
L'implémentation proposée repose sur la représentation interne des complexes par les enregistrements.
Début
Retourner(constC(rl(z1)+rl(z2), im(z1)+im(z2))
Fin
Début
Retourner(constC(rl(z1)-rl(z2), im(z1)-im(z2))
Fin
Remarque
Notons que parmi les fonctions écrites implémentant les opérations du TAD COMPLEXE, certaines
sont dites de base (telles que: constC, rl et im), leur corps dépend du type choisi pour implémenter
la sorte en question, et d'autres sont valables quelque soit le type considéré (telles que: addC,
soustC, module, etc.). En changeant de type pour complexe (passer de l'enregistrement au tableau
par exemple), ces fonctions restent inchangées (aspect réutisation).