Vous êtes sur la page 1sur 9

Université Abdelhamid Mehri – Constantine 2

2022-2023. Semestre 3

Algorithmique et Structures de Données (ASD)

– Cours –
Chapitre 03 : Structures de données linéaires : Liste, Pile et
File
Partie01: Introduction aux Types Abstraits de Données (TAD)

Chargée de Cours : Mme Dj.Hammoud

Objectifs du cours
Objectif 1: Cette première partie du cours permet d'initier les étudiants au
concept de Type Abstrait de Données (TAD),
 A quoi sert un TAD ?
 Comment s'en servir?
 Pourquoi recourir au TAD dans l'élaboration des algorithmes.

1. Introduction
1.1. Structures de Données (S.D): Moyen pour stocker et organiser les données pour en
faciliter l’accès et la modification.

Une Structure de Données (S.D) regroupe :


 un certain nombre de données à gérer, et
 un ensemble d’opérations pouvant être appliquées pour ces données
La résolution de problèmes algorithmiques requiert presque toujours la combinaison de structures
de données et d’algorithmes sophistiqués pour la gestion et la recherche dans ces structures.
D’autant plus vrai qu’on a à traiter des volumes de données importants.

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 (R.I) de ces données ainsi que la mise en oeuvre
des opérations ( leur implémentation).

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 avantages des TAD sont:


 Prise en compte de types de données complexes.
 Séparation entre les services (données + opérations) et le codage.
 L'utilisateur d'un TAD n'a pas besoin de connaître les détails du codage.
 Ecriture de programmes modulaires.
 Abstraction des services qui favorise la réutilisation.

2. Definition d’un TAD


Un Type Abstrait de Données (TAD) est donc caractérisé par :
• Son Nom,
• Les Sortes (domaine de valeurs) qu’il manipule, Signature
• Les Opérations sur les Données,
• Les Propriétés de ces Opérations. Axiomes

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 (formules) 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
Sorte booléen TAD NATUREL
Opérations Sorte nat
vrai : → booléen Opérations
faux : → booléen
0 : → nat
_ et _ : booléen, booléen → booléen
succ : nat → nat
_ ou _ : booléen, booléen → booléen
_ + _ : nat , nat → nat
_ - _ : nat , nat → nat
_ * _ : nat , nat → nat
_ ^_ : nat , nat → nat
non_: booléen → booléen

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.

Signature Exemple de données Décision Justification


du TAD
BOOLEEN vrai et faux Correcte syntaxiquement
non true Incorrecte syntaxiquement "true" non définie
non(faux et vrai) correcte syntaxiquement
Incorrecte syntaxiquement "and" non définie
faux and vrai
Incorrecte syntaxiquement Le nombre d'arguments
non(vrai, faux)
n'est pas respecté

NATUREL succ(succ(zero)) Incorrecte syntaxiquement "zero" non définie


1+succ(0) Incorrecte syntaxiquement "1" non définie
succ(0) ^succ(0) correcte syntaxiquement
succ(succ(0)) correcte syntaxiquement
succ(succ(succ(0))) correcte 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 (
ex: a+b, c*d, _et_, ...), le "_" désigne la position de l'argument.
 Notation Infixée, les arguments sont situées avant le nom de l'opération ( ab+, cd*
 Notation Préfixée, les arguments sont situées après le nom de l'opération (succ(a),
non(d) ), 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), les sortes correspondant aux noms de sortes
nouveaux.
On appelle sorte(s) prédéfinie(s), 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

_ + _ : nat , nat → nat


_ - _ : nat , nat → nat
_ * _ : nat , nat → nat Internes non constructeurs
_ ^_ : nat , nat → nat

_=_: nat, nat → booléen observateur

1.1 Axiomes (Propriétés)

Les proprié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 ainsi que les propriétes des opérations à faire sur ces
données.
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;
2- non faux ≡ vrai; X-Y définie ssi X  Y (convention
3- vrai et b ≡ b; pour éviter de sortir des entiers
4- faux et b ≡ faux; naturels)
5- vrai ou b ≡ vrai; Axiomes
6- faux ou b ≡ b; 1- X + 0 ≡ X;
2- X + succ(Y) ≡ succ(X + Y);
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);
1.2 Intérêt et implémentation d'un TAD
Nous notons l'intérêt de spécifier (décrire) les Structures de Données (S.D) utilisées dans
un algorithme avec un TAD à travers l'exemple ci dessous. Nous montrons comment passer
d'une telle spécification (définition ou description) à son implémentation (en
algorithmique) ou sa codification au niveau d'un programme en utilisant n'importe quel
langage de programmation.

Exercice 1
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

addC : complexe, complexe → complexe


soustC : complexe, complexe → complexe Internes non constructeurs

... /* Nous pouvons tjs enrichir un TAD par d’autres Opérations (O.P)
Variables
r1, r2, r3, r4 : réel,
z, z1, z2 : complexe

Axiomes
1- rl(constC(r1,r2)) ≡ r1 /* Constructeur en partie gauche
2- im(constC(r1,r2)) ≡ r2
3- module((constC(r1,r2)) ≡ sqrt(r1*r1 + r2*r2)) Sachant que les opérations +, * et sqrt
sont définies dans le TAD
REEL

4- addC(constC(r1,r2), constC(r3, r4)) ≡ constC(r1+r3, r2+r4)


5- soustC(constC(r1,r2), constC(r3, r4)) ≡ constC(r1-r3, r2-r4)

On peut écrire d'une autre manière ces 3 derniers axiomes: (cette manière favorise la
réutilisation de l’axiome à l’implémentation et elle consiste à utiliser des variables ds la
partie gauche de l’axiome et non des opérations constructeur (ds la partie droite les
opérations constructeur sans pbm)
module(z) ≡ sqrt(rl(z)*rl(z) + im(z)*im(z)))
addC(z1,z2) ≡ constC(rl(z1)+rl(z2), im(z1)+im(z2))
soustC(z1,z2) ≡ constC(rl(z1)-rl(z2), im(z1)-im(z2))

Cette 2eme forme n’utilise pas les constructeurs ds les arguments (partie gauche, mais des
variables de la sorte définie, ici Z: complexe) et elle permet ainsi d’utiliser l’axiome à
l’implémentation; c’est la forme qu’il faut tjs tnter de trouver.

1.2.1. Implémentation d'un TAD


Maintenant, pour implémenter un TAD (donc lui associer une Representation Interne
(R.I) donnée ou un Type et des algorithmes), il suffit d'appliquer les correspondances
résumées dans le tableau suivant :

Concepts dans un TAD (ou Implémentation dans un langage quelconque


Elements du TAD) (ici pseudo-code)
Sorte Soit un:
 Type de base du langage (int, real, char, ...)
 Type défini par le concepteur en fonction des
types de base (tableau, enreg, ...)
Opération non constructeur ou Fonction
observateur
 Profil  Entête
 Axiome  Corps (instructions tirées de l’axiome)
des fois c’est l’axiome lui mm
Opération constructeur Fonction
 Profil  Entête
 Corps (instructions) est donné selon le type
implémentant la sorte définie dans le TAD
Précondition d'une opération Condition d'appel (ou d'utilisation de la
fonction) à tester avant l’appel de la fonc

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.

TAD COMPLEXE Implémentation dans un langage quelconque (ici juste le pseudo


code )
Sortes Types
 Réel  REAL
 Complexe  Complexe = Enregistrement
R, M: real
Fin
Opérations non constructeurs ou observateurs
Fonction addC (D z1, z2: complexe): complexe
profil Déclarations / declarez tt les fonc utilisées
addC : complexe, complexe → complexe Fonction rl (D z:complexe): real
debut ... fin
Fonction im (D z:complexe): real
debut ... fin
Fonction constC(D r1, r2:real): complexe
debut ... fin
Axiome Début
addC(z1,z2) ≡ constC (rl (z1)+rl(z2), im Retourner ( constC (rl(z1)+rl(z2), im(z1)+im(z2))
(z1)+im(z2)) Fin

Fonction soustC (D z1, z2: complexe): complexe


profil Déclarations
soustC : complexe, complexe → complexe Fonction rl (D z:complexe): real
debut ... fin
Fonction im (D z:complexe): real
debut ... fin
Fonction constC (D r1, r2:real): complexe
debut ... fin
Début
Retourner (constC (rl(z1)-rl(z2), im(z1)-im(z2))
Fin
Axiome
soustC(z1,z2) ≡ constC(rl(z1)-rl(z2), im(z1)-
Fonction rl (D z:complexe): real
im(z2)) Début
Retourner (z.R) /*pas d’axiome à utiliser directement,
ici
profil l’implementation dépend du type
rl : complexe → réel enreg
Fin
Axiome
rl(constC(r1,r2)) ≡ r1 /*cet axiome ne peut Fonction im (D z:complexe): real
etre utilisé directement ds l’implémentation Début
(mais il a définie le sens de l’operation) Retourner(z.M)
Fin
profil
im : complexe → réel Fonction module (D z: complexe): real
Axiome Déclarations
Im (constC (r1,r2)) ≡ r2 /*mm chose pr op im Fonction rl(D z:complexe): real
debut ... fin

profil Fonction im(D z:complexe): real


module: complexe→ réel debut ... fin
Début
Retourner (sqrt (rl(z)*rl(z) + im (z)*im (z)))
Axiome Fin
module(z) ≡ sqrt (rl (z)*rl(z) + im (z)*im(z)))
/*axiome utilisable directement en
implémentation

constC : réel, réel → complexe Fonction ConstC(D r1:real, D r2:real): complexe


Déclaration
z: complexe
Début
z.R=r1
z.M=r2
Retourner(z) /*l’op constructeur est implémentée
avec le type déclaré, ici enreg
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 et independantes
des types declarés (aspect réutilisation).

Revoir la vidéo 16 et 17 pr la construction de TAD et leur Implémentation.

Vous aimerez peut-être aussi