Vous êtes sur la page 1sur 48

Structures de Données

Avancées

Types Abstraits de Données


Piles, Files & Listes
[1ère année Master IESE, Semestre 1]
Faculté des sciences de Rabat

Par
Prof. B. AHIOD
(ahiod@fsr.ac.ma)
2023-2024

Objectifs

• Introduire la Notion de Type Abstrait de Données (TAD)


⁻ Spécification
⁻ Implémentation

• Etudier les structures linéaires classiques


⁻ Piles
⁻ Files
⁻ Listes

Master IESE Structures de données avancées (2023-2024) 2

1
Types Abstraits de Données
(TADs)
Spécification & Implémentation

Notion de Type Abstrait de Données


(TAD)
₋ La conception d’un algorithme est indépendante
de toute implantation

₋ La représentation des données n'est pas fixée ;


celles-ci sont considérées de manière abstraite

₋ On s’intéresse à l’ensemble des opérations sur les


données, et aux propriétés des opérations, sans
dire comment ces opérations sont réalisées

₋ On parle de Type Abstrait de Données (TAD)

Master IESE Structures de données avancées (2023-2024) 4

2
Définition d’un TAD

• Un TAD (Data Abstract Type) est un ensemble de valeurs muni d’opérations sur
ces valeurs, sans faire référence à une implémentation particulière.

• Exemples :
₋ Dans un algorithme qui manipule des entiers, on s’intéresse, non pas à la
représentation des entiers, mais aux opérations définies sur les entiers : +, -, *, /

₋ Type booléen, ensemble de 2 valeurs (faux, vrai) muni des opérations : non, et, ou

• Un TAD est caractérisé par :


₋ sa signature : définit la syntaxe du type et des opérations ;
₋ sa sémantique : définit les propriétés des opérations.

Master IESE Structures de données avancées (2023-2024) 5

Signature d’un TAD


• Comporte :
₋ Le nom du TAD ;
₋ Les noms des types des objets utilisés par le TAD ;
₋ Pour chaque opération, l’énoncé des types des objets
qu’elle reçoit et qu’elle renvoie.

• Décrite par les paragraphes :


₋ Type
₋ Utilise
₋ Opérations

Master IESE Structures de données avancées (2023-2024) 6

3
Signature d’un TAD
Exemple : TAD Booléen
Nom du
TAD
Type Booléen
Opérations Nom de l'opération
vrai :  Booléen Deux arguments
faux :  Booléen de type Booléen
non : Booléen  Booléen Type valeur de
et : Booléen x Booléen  Booléen retour
ou : Booléen x Booléen  Booléen

Master IESE Structures de données avancées (2023-2024) 7

Sémantique d’un TAD

• Précise :
₋ Les domaines de définition (ou d’application) des
opérations ;
₋ Les propriétés des opérations.

• Décrite par les paragraphes :


₋ Préconditions
₋ Axiomes

Master IESE Structures de données avancées (2023-2024) 8

4
Exemple 1 de TAD
(TAD Booléen)
Type Booléen
Opérations
vrai :  Booléen
faux :  Booléen
non : Booléen  Booléen
et : Booléen × Booléen  Booléen
ou : Booléen × Booléen  Booléen
Préconditions

Axiomes Aucune
Soit, a, b : Booléen précondition
non(vrai) = faux
non(non(a)) = a
vrai et a = a
faux et a = faux
a ou b = non(non(a) et non(b))

Master IESE Structures de données avancées (2023-2024) 9

Exemple 2 de TAD
(TAD Vecteur)
Type Vecteur
Utilise Entier, Elément
Opérations
vect : Entier  Vecteur
changer_ième : Vecteur x Entier x Elément  Vecteur
ième : Vecteur x Entier  Elément
taille : Vecteur  Entier
Préconditions
vect(i) est_défini_ssi i ≥ 0
ième(v,i) est_défini_ssi 0 ≤ i < taille(v)
changer_ième(v,i,e) est_défini_ssi 0 ≤ i < taille(v)
Axiomes
Soit, i, j : Entier, e : Elément, v : Vecteur
si 0 ≤ i < taille(v) alors ième(changer_ième(v,i,e),i) = e
si 0 ≤ i < taille(v) et 0 ≤ j < taille(v) et i ≠ j
alors ième(changer_ième(v,i,e),j) = ième(v,j)
taille(vect(i)) = i
taille(changer_ième(v,i,e)) = taille(v)
Master IESE Structures de données avancées (2023-2024) 10

5
Opérateurs
• Trois catégories d'opérateurs (ou de primitives) :

₋ Constructeurs : type spécifié apparaît, uniquement,


comme résultat ;

₋ Observateurs : type spécifié apparaît, uniquement,


comme argument ;

₋ Transformateurs : type spécifié apparaît, à la fois,


comme argument et comme résultat ;

• Constante : opérateur sans argument

Master IESE Structures de données avancées (2023-2024) 11

Opérations Partielles

• Une opération peut ne pas être définie partout

• Cela dépend de son domaine de définition

• Ceci est traité dans le paragraphe Préconditions

• Exemple :
Opérations ième et changer_ième du TAD Vecteur

Master IESE Structures de données avancées (2023-2024) 12

6
Réutilisation des TADs

• Quand on définit un type, on peut réutiliser des types déjà


définis

• La signature du type défini est l'union des signatures des


types utilisés enrichie des nouvelles opérations

• Le type hérite des propriétés des types qui le constituent

• Exemples :
Types Entier et Elément utilisés par le TAD Vecteur

Master IESE Structures de données avancées (2023-2024) 13

Notion de Structure de Données


• On dit aussi structure de données concrète

• Correspond à l’implémentation d’un TAD

• Composée d’un algorithme pour chaque opération, plus


éventuellement des données spécifiques à la structure
pour sa gestion

• Un même TAD peut donner lieu à plusieurs structures de


données, avec des performances différentes

Master IESE Structures de données avancées (2023-2024) 14

7
Implémentation d’un TAD
• Pour implémenter un TAD :
₋ Déclarer la structure de données retenue pour représenter le TAD : L’interface
₋ Définir les opérations primitives dans un langage particulier : La réalisation

• Exigences :
₋ Conforme à la spécification du TAD ;
₋ Efficace en terme de complexité d’algorithme.

• Pour implémenter, on utilise :


₋ Les types élémentaires (entiers, caractères, ...)
₋ Les pointeurs ;
₋ Les tableaux et les enregistrements ;
₋ Les types prédéfinis.

• Plusieurs implémentations possibles pour un même TAD


Master IESE Structures de données avancées (2023-2024) 15

Implémentation d’un TAD en C


• Utiliser la programmation modulaire (voir TPs) :
₋ Programme découpé en plusieurs fichiers, même de petites tailles (réutilisabilité, lisibilité,
etc.)
₋ Chaque composante logique (un module) regroupe les fonctions et types autour d'un
même thème.

• Pour chaque module truc, créer deux fichiers :


₋ fichier truc.h : l'interface (la partie publique) ; contient la spécification de la structure ;
₋ fichier truc.c : la définition (la partie privée) ; contient la réalisation des opérations
fournies par la structure. Il contient au début l'inclusion du fichier truc.h

• Tout module ou programme principal qui a besoin d'utiliser les fonctions du module truc,
devra juste inclure le truc.h

• Un module C implémente un TAD :


₋ L'encapsulation : détails d'implémentation cachés ; l'interface est la partie visible à un
utilisateur
₋ La réutilisation : placer les deux fichiers du module dans le répertoire où l'on développe
l'application.
Master IESE Structures de données avancées (2023-2024) 16

8
Implémentation d’un TAD
Exemple : TAD Booléen
/* fichier Booleen.c */

L'interface La définition #include "Booleen.h"


(partie publique) (partie privée)
Booleen et(Booleen x, Booleen y) {
/* fichier Booleen.h */ if (x == faux)
return faux;
#ifndef _BOOLEEN else return y;
#define _BOOLEEN }

typedef enum (faux,vrai) Booleen; Booleen ou(Booleen x, Booleen y) {


if (x == vrai)
Booleen et(Booleen x, Booleen y); return vrai;
Booleen ou(Booleen x, Booleen y); else return y;
Booleen non(Booleen x) ; }

#endif Booleen non(Booleen x) {


if (x == vrai)
return faux;
else return vrai;
Master IESE Structures de données } (2023-2024)
avancées 17

Structures de Données
Linéaires

Piles, Files & listes


Master IESE 2023-2024

9
Objectifs

• Étude des structures de données linéaires : piles, files et listes

• Une structure linéaire est un arrangement linéaire d'éléments


liés par la relation successeur
₋ Exemple : Un tableau (la relation successeur est implicite).

• Pour chaque structure, on présente :


₋ une définition abstraite ;
₋ les différentes représentations en mémoire ;
₋ une implémentation en langage C ;
₋ quelques applications.
Master IESE Structures de données avancées (2023-2024) 19

Les Piles
(Stacks)

Master IESE 2023-2024

10
Notion de Pile (Stack)
• Les piles sont très utilisées en informatique

• Notion intuitive :
₋ pile d'assiettes, pile de dossiers à traiter, …

• Une pile est une structure linéaire permettant de stocker et


de restaurer des données selon un ordre LIFO (Last In, First
Out ou « dernier entré, premier sorti »)

• Dans une pile :


₋ Les insertions (empilements) et les suppressions (dépilements) sont
restreintes à une extrémité appelée sommet de la pile.

Master IESE Structures de données avancées (2023-2024) 21

Exemple de Pile

Empiler B Dépiler D
Empiler A Empiler C
Empiler E
Empiler D

Master IESE Structures de données avancées (2023-2024) 22

11
Type Abstrait Pile
Type Pile
Utilise Elément, Booléen
Opérations
pile_vide :  Pile
est_vide : Pile  Booléen
empiler : Pile x Elément  Pile
dépiler : Pile  Pile
sommet : Pile  Elément
Préconditions
dépiler(p) est-défini-ssi est_vide(p) = faux
sommet(p) est-défini-ssi est_vide(p) = faux
Axiomes
Soit, e : Element, p : Pile
est_vide(pile_vide) = vrai
est_vide(empiler(p,e)) = faux
dépiler(empiler(p,e)) = p
sommet(empiler(p,e)) = e

Master IESE Structures de données avancées (2023-2024) 23

Opérations sur une Pile


• pile_vide :  Pile
opération d'initialisation ; la pile créée est vide

• est_vide : Pile  Booléen


teste si pile vide ou non

• sommet : Pile  Elément


permet de consulter l'élément situé au sommet ; n'a pas de sens si pile vide

• empiler : Pile x Elément  Pile


ajoute un élément dans la pile

• dépiler : Pile  Pile


enlève l'élément situé au sommet de la pile ; n'a pas de sens si pile vide

Master IESE Structures de données avancées (2023-2024) 24

12
Représentation d'une Pile
• Représentation contiguë (par tableau) :
₋ Les éléments de la pile sont rangés dans un tableau
₋ Un entier représente la position du sommet de la pile

• Représentation chaînée (par pointeurs) :


₋ Les éléments de la pile sont chaînés entre eux
₋ Un pointeur sur le premier élément désigne la pile et
représente le sommet de cette pile
₋ Une pile vide est représentée par le pointeur NULL

Master IESE Structures de données avancées (2023-2024) 25

Pile Contiguë
Pile 6 /* Pile contiguë en C */

5 // taille maximale pile


#define MAX_PILE 7
4
// type des éléments
3 10 3 typedef int Element;
sommet
20 2 // type Pile
5 1 typedef struct {
Element elements[MAX_PILE];
Tableau de taille 50 0 int sommet;
maximale 7 } Pile;
elements

Master IESE Structures de données avancées (2023-2024) 26

13
Spécification d'une Pile Contiguë
/* fichier "Tpile.h" */
#ifndef _PILE_TABLEAU
#define _PILE_TABLEAU

#include "Booleen.h"

// Définition du type Pile (implémentée par un tableau)


#define MAX_PILE 7 /* taille maximale d'une pile */
typedef int Element; /* les éléments sont des int */

typedef struct {
Element elements[MAX_PILE]; /* les éléments de la pile */
int sommet; /* position du sommet */
} Pile; type Pile : une structure à
deux champs
// Déclaration des fonctions gérant la pile
Pile pile_vide ();
Pile empiler ( Pile p, Element e );
Pile depiler ( Pile p );
Element sommet ( Pile p );
Booleen est_vide ( Pile p );

#endif

Master IESE Structures de données avancées (2023-2024) 27

Réalisation d'une Pile Contiguë


/* fichier "Tpile.c" */

#include "Tpile.h"
// ajout d'un élément
// Définition des fonctions gérant la pile Pile empiler(Pile p, Element e) {
if (p.sommet >= MAX_PILE-1) {
// initialiser une nouvelle pile printf("Erreur : pile pleine !\n");
Pile pile_vide() { exit(-1);
Pile p; }
p.sommet = -1; (p.sommet)++;
return p; (p.elements)[p.sommet] = e;
} return p;
}
// tester si la pile est vide
Booleen est_vide(Pile p) { // enlever un élément
if (p.sommet == -1) return vrai; Pile depiler(Pile p) {
return faux; /* pré-condition : pile non vide !*/
} if (est_vide(p)) {
printf("Erreur: pile vide !\n");
// Valeur du sommet de pile exit(-1);
Element sommet(Pile p) { }
/* pré-condition : pile non vide ! */ p.sommet--;
if (est_vide(p)) { return p;
printf("Erreur: pile vide !\n"); }
exit(-1);
}
return (p.elements)[p.sommet];
}

Master IESE Structures de données avancées (2023-2024) 28

14
Exemple d'Utilisation d'une Pile Contiguë
/* fichier "UTpile.c" */
#include <stdio.h>
#include "Tpile.h"

int main () {
Pile p = pile_vide();

p = empiler(p,50);
p = empiler(p,5);
p = empiler(p,20);
p = empiler(p,10);
printf("%d au sommet après empilement de 50, 5, 20 et"
" 10\n", sommet(p));
p = depiler(p);
p = depiler(p);
printf("%d au sommet après dépilement de 10 et 20\n",
sommet(p));
return 0;
}

Master IESE Structures de données avancées (2023-2024) 29

Pile chaînée

Pile /* Pile chaînée en C */


Sommet de la pile
pointée par p // type des éléments
typedef int element;

10 20 // type Cellule
typedef struct cellule {
element valeur;
struct cellule *suivant;
p Pointeur } Cellule;
NULL
Cellule contenant
la valeur 5 // type Pile
50
typedef Cellule *Pile;
Pointeur sur cellule
suivante
Master IESE Structures de données avancées (2023-2024) 30

15
Spécification d'une Pile Chaînée
/* fichier "Cpile.h" */
#ifndef _PILE_CHAINEE
#define _PILE_CHAINEE

#include "Booleen.h"

// Définition du type Pile (implémentée par pointeurs)


typedef int Element; /* les éléments sont des int */

typedef struct cellule { Une cellule contient un


Element valeur; élément et un pointeur sur
struct cellule *suivant;
} Cellule;
l'élément suivant

typedef Cellule *Pile; type Pile : un pointeur de


Cellule
// Déclaration des fonctions gérant la pile
Pile pile_vide ();
Pile empiler ( Pile p, Element e );
Pile depiler ( Pile p );
Element sommet ( Pile p );
Booleen est_vide ( Pile p );

#endif
Master IESE Structures de données avancées (2023-2024) 31

Réalisation d'une Pile Chaînée


/* fichier "Cpile.c" */ Pile empiler(Pile p, Element e) {
Cellule * pc;
#include "alloc.h" pc=(Cellule *)malloc(sizeof(Cellule));
#include "Cpile.h" pc->valeur=e;
pc->suivant=p;
Pile pile_vide(void) { return pc; allouer un espace
return NULL; } mémoire pour une
} nouvelle cellule
int est_vide(Pile p) { Pile depiler(Pile p) {
return (p == NULL); /* pré-condition: pile non vide ! */
} Cellule * pc = p;
if (est_vide(p)) {
Element sommet(Pile p) { printf("Erreur: pile vide !\n");
/* pré-condition: pile non vide ! */ exit(-1);
if (est_vide(p)) { }
printf("Erreur: pile vide !\n"); p=p->suivant;
exit(-1); free(pc); libérer l'espace
} return p; mémoire occupé
}
return p->valeur; par la cellule
}

Master IESE Structures de données avancées (2023-2024) 32

16
Exemple d'Utilisation d'une Pile Chaînée
/* fichier "UCpile.c" */
#include <stdio.h>
#include "Cpile.h"

int main () {
Pile p = pile_vide();

p = empiler(p,50);
p = empiler(p,5);
p = empiler(p,20);
p = empiler(p,10);
printf("%d au sommet après empilement de 50, 5, 20 et"
" 10\n", sommet(p));
p = depiler(p);
p = depiler(p);
printf("%d au sommet après dépilement de 10 et 20\n",
sommet(p));
return 0;
}

Master IESE Structures de données avancées (2023-2024) 33

Complexité

• Les opérations sur les piles sont toutes en O(1)

• Ceci est valable pour les deux représentations proposées

Master IESE Structures de données avancées (2023-2024) 34

17
Applications d'une Pile
Exemples (1)
• Vérification du bon équilibrage d’une expression parenthèsée :
₋ Pour vérifier qu'une expression parenthésée est équilibrée, à chaque
rencontre d'une parenthèse ouvrante on l'empile et à chaque rencontre
d'une parenthèse fermante on dépile ;

• Evaluation des expressions arithmétiques postfixées (expressions


en notation polonaise inverse) :
₋ Pour évaluer une telle expression, on applique chaque opérateur aux deux
opérandes qui le précédent. Il suffit d'utiliser une pile dans laquelle les
opérandes sont empilés, alors que les opérateurs dépilent deux éléments,
effectuent l'opération et empilent le résultat. Par exemple, l'expression
postfixée 2 3 5 * + 1 – s'évalue comme suit : ((2 (3 5 *) +) 1 –) = 16 ;

• Conversion d’une expression en notation infixe (parenthèsée) en


notation postfixée ;
Master IESE Structures de données avancées (2023-2024) 35

Applications d'une Pile


Exemples (2)
• Gestion par le compilateur des appels de fonctions :
₋ les paramètres, l’adresse de retour et les variables locales sont
stockés dans la pile de l’application

• Mémorisation des appels de procédures imbriquées


au cours de l’exécution d’un programme, et en
particulier les appels des procédures récursives ;

• Parcours « en profondeur » de structures d'arbres :


₋ (voir chapitre arbres)

Master IESE Structures de données avancées (2023-2024) 36

18
Exercices
1. Ecrire un programme C qui implémente une pile d’entiers. Ce programme affiche à
l'utilisateur un menu avec les options suivantes :
1. empiler un entier dans la pile ;
2. dépiler un entier de la pile ;
3. taille de la pile ;
4. sommet de la pile ;
5. afficher le contenu de la pile ;
6. quitter le programme.

2. Ecrire un programme C qui lit une séquence de nombres entiers et l’affiche dans l’ordre
inversé. Indication : Utiliser une pile.
3. [Enoncé TP2] Ecrire un programme C permettant de vérifier si une expression
arithmétique contenant les délimiteurs [, }, ), {, ( et ], est correcte ou non
Exemples :
{x + (100 - [a + b]) - d} est une expression correcte.
{x + (y - [a + b]) * 20 - [d + c} est une expression incorrecte.

4. Ecrire un programme C pour évaluer une expression écrite en notation postfixée.


Exemple :
9 3 4 * 8 + 4 / – est une expression en notation postfixée. Elle s’évalue comme 9 – ((3 * 4) + 8) / 4 et sa
saleur est 4

Master IESE Structures de données avancées (2023-2024) 37

Les Files
(Queues)

Master IESE 2023-2024

19
Notion de File (Queue)
• Les files sont très utilisées en informatique

• Notion intuitive :
₋ File d'attente à un guichet, file de documents à imprimer, …

• Une file est une structure linéaire permettant de stocker et de


restaurer des données selon un ordre FIFO (First In, First Out
ou « premier entré, premier sorti »)

• Dans une file :


• Les insertions (enfilements) se font à une extrémité appelée queue de la file et
les suppressions (défilements) se font à l'autre extrémité appelée tête de la file

Master IESE Structures de données avancées (2023-2024) 39

Exemple de File
Enfiler A
Enfiler E Défiler B
Enfiler B
Enfiler C
Enfiler D

Master IESE Structures de données avancées (2023-2024) 40

20
Type Abstrait File
Type File
Utilise Elément, Booléen
Opérations
file_vide :  File
est_vide : File  Booléen
enfiler : File x Elément  File
défiler : File  File
tête : File  Elément
Préconditions
défiler(f) est-défini-ssi est_vide(f) = faux
tête(f) est-défini-ssi est_vide(f) = faux
Axiomes
Soit, e : Element, f : File
est_vide(pile_vide) = vrai
est_vide(enfiler(f,e)) = faux
si est_vide(f) = vrai alors tête(enfiler(f,e)) = e
si est_vide(f) = faux alors tête(enfiler(f,e)) = tête(f)
si est_vide(f) = vrai alors défiler(enfiler(f,e)) = file_vide
si est_vide(f) = faux
alors défiler(enfiler(f,e)) = enfiler(défiler(f),e)

Master IESE Structures de données avancées (2023-2024) 41

Opérations sur une File


• file_vide :  File
opération d'initialisation ; la file créée est vide

• est_vide : File  Booléen


teste si file vide ou non

• tête : File  Elément


permet de consulter l'élément situé en tête de file ; n'a pas de sens si file
vide

• enfiler : File x Elément  File


ajoute un élément dans la file

• défiler : File  File


enlève l'élément situé en tête de file ; n'a pas de sens si file vide

Master IESE Structures de données avancées (2023-2024) 42

21
Représentation d'une File
• Représentation contiguë (par tableau) :
₋ Les éléments de la file sont rangés dans un tableau
₋ Deux entiers représentent respectivement les positions de la tête
et de la queue de la file

• Représentation chaînée (par pointeurs) :


₋ Les éléments de la file sont chaînés entre eux
₋ Un pointeur sur le premier élément désigne la file et représente
la tête de cette file
₋ Un pointeur sur le dernier élément représente la queue de file
₋ Une file vide est représentée par le pointeur NULL

Master IESE Structures de données avancées (2023-2024) 43

Représentation Contiguë d'une File


(par tableau simple)

• tête de file : position précédant premier élément


• queue de file : position du dernier élément

• Initialisation : tête  queue  -1

• Inconvénient :
₋ On ne peut plus ajouter des éléments dans la file, alors qu'elle n'est
pas pleine !

Master IESE Structures de données avancées (2023-2024) 44

22
Représentation Contiguë d'une File
(par tableau simple) (1)

0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
tab tab 5 2 10 20 30 40 50
tete -1 tete -1
queue -1 File initialement vide de queue 6 File après ajout de 5, 2,
taille maximale = 10 10, 20, 30, 40 et 50
(1) (2)

0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
tab 10 20 30 40 50 tab
tete 1 tete 6
queue 6 File après suppression queue 6 File après suppression
de 5 et 2 de 10, 20, 30, 40 et 50
(3) (4)

Master IESE Structures de données avancées (2023-2024) 45

Représentation Contiguë d'une File


(par tableau simple) (2)

0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
tab tab 5 15 10

tete 6 tete 6
queue 6 queue 9 File après ajout de
File vide 5, 15 et 10
(5) (6)

0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
tab 10 tab 10

tete 8 tete 8
queue 9 File après queue 9 On ne peut plus
suppression 5 et 15 ajouter dans la file !!
(7) (8)

Master IESE Structures de données avancées (2023-2024) 46

23
File Contiguë
/* File contiguë en C */
File
// taille maximale file
#define MAX_FILE 10
0 1 2 3 4 5 6 7 8 9
tab 10 20 30 40 50
// type des éléments
tete 1 typedef int Element;
queue 6 Tableau de taille
maximale 10 // type File
typedef struct {
Position qui précède le Element tab[MAX_FILE];
premier élément de la file
int tete;
int queue;
Position du dernier
} File;
élément de la file

Master IESE Structures de données avancées (2023-2024) 47

Spécification d'une File Contiguë


/* fichier "Tfile.h" */
#ifndef _FILE_TABLEAU
#define _FILE_TABLEAU

#include "Booleen.h"

// Définition du type File (implémentée par un tableau simple)


#define MAX_FILE 10 /* taille maximale d'une file */
typedef int Element; /* les éléments sont des int */

typedef struct {
Element tab[MAX_FILE]; /* les éléments de la file */
int tete; /* position précédant premier élément */
int queue; /* position dernier élément */
} File; type File : une structure à
trois champs
// Déclaration des fonctions gérant la pile
File file_vide ();
File enfiler ( File f, Element e );
File defiler ( File f );
Element tete ( File f );
Booleen est_vide ( File f );

#endif

Master IESE Structures de données avancées (2023-2024) 48

24
Réalisation d'une File Contiguë
/* fichier "Tfile.c" */

#include "Tfile.h"
// ajout d'un élément
// Définition des fonctions gérant la file File enfiler(File f, Element e) {
if (f.queue == MAX_FILE-1) {
// initialiser une nouvelle file printf("Erreur: on ne peut ajouter !\n");
File file_vide() { exit(-1);
File f; }
f.queue = f.tete = -1; (f.queue)++;
return f; (f.tab)[f.queue] = e;
} return f;
}
// tester si la file est vide
Booleen est_vide(File f) { // enlever un élément
if (f.tete == f.queue) return vrai; File defiler(File f) {
return faux; /* pré-condition : file non vide !*/
} if (est_vide(f)) {
printf("Erreur: file vide !\n");
// Valeur en tête de file exit(-1);
Element tete(File f) { }
/* pré-condition : file non vide ! */ f.tete++;
if (est_vide(f)) { return f;
printf("Erreur: file vide !\n"); }
exit(-1);
}
return (f.tab)[f.tete+1];
}
Master IESE Structures de données avancées (2023-2024) 49

Représentation Contiguë d'une File


(par tableau simple avec décalage)

• Décaler les éléments de la file après chaque suppression

• Inconvénient :
₋ décalage très coûteux, si la file contient beaucoup d'éléments

Master IESE Structures de données avancées (2023-2024) 50

25
Représentation Contiguë d'une File
(par tableau simple avec décalage) (1)

0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
tab tab 5 2 10 20 30 40 50
tete -1 tete -1
queue -1 File initialement vide de queue 6 File après ajout de 5, 2,
taille maximale = 10 10, 20, 30, 40 et 50
(1) (2)

0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
tab 10 2 30 40 50 tab
0
tete -1 tete -1
queue 4 File après suppression queue -1 File après suppression
de 5 et 2 de 10, 20, 30, 40 et 50
(3) (4)

Master IESE Structures de données avancées (2023-2024) 51

Représentation Contiguë d'une File


(par tableau simple avec décalage) (2)

0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
tab tab 5 15 10

tete -1 tete -1
queue -1 queue 2 File après ajout de
File vide 5, 15 et 10
(5) (6)

0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
tab 10 tab 10 5 6 20 8 35 25 33 4 80

tete -1 tete 8
File après Après ajout de 5, 6, 20, 8,
queue 0 queue 9
suppression 5 et 15 35, 25, 33, 4 et 80, File
(7) (8) pleine!!

Master IESE Structures de données avancées (2023-2024) 52

26
Représentation Contiguë d'une File
(Par tableau circulaire)

• Gérer le tableau de manière circulaire : suivant de l'élément à


la position i est l'élément à la position (i+1) modulo MAX_FILE

• Convention : file autorisée à contenir MAX_FILE-1 éléments

• Initialisation : tête  queue  0

• Toutes les places dans le tableau sont exploitées

Master IESE Structures de données avancées (2023-2024) 53

File Contiguë Circulaire


(Exemple)

Master IESE Structures de données avancées (2023-2024) 54

27
Représentation Contiguë d'une File
(par tableau circulaire) (1)

0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
tab tab 5 2 10 20 30 40 50
tete 0 tete 0
File initialement vide
queue 0 queue 7 File après ajout de 5, 2,
qui peut contenir au
10, 20, 30, 40 et 50
(1) plus 9 éléments (2)

0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
tab 10 20 30 40 50 tab
tete 2 tete 7
queue 7 File après suppression queue 7 File après suppression
de 5 et 2 de 10, 20, 30, 40 et 50
(3) (4)

Master IESE Structures de données avancées (2023-2024) 55

Représentation Contiguë d'une File


(par tableau circulaire) (2)

0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
tab tab 10 5 15

tete 7 tete 7
queue 7 queue 0 File après ajout de
File vide 5, 15 et 10
(5) (6)

0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
tab 10 15 tab 10 5 6 20 8 35 25 33 15

tete 8 tete 8
File après Après ajout de 5, 6, 20, 8,
queue 0 queue 7
suppression 5 35, 25, et 33,
(7) (8) File pleine!!

Master IESE Structures de données avancées (2023-2024) 56

28
Réalisation d'une File Contiguë Circulaire
/* fichier "TCfile.c" */

#include "Tfile.h"

// Définition des fonctions gérant la file // ajout d'un élément


File enfiler(File f, Element e) {

// initialiser une nouvelle file if (f.tete == (f.queue+1) % MAX_FILE) {

File file_vide() { printf("Erreur : file pleine !\n");


File f; exit(-1);

f.queue = f.tete = 0; }

return f; f.queue=(f.queue+1) % MAX_FILE;

} (f.tab)[f.queue] = e;
return f;

// tester si la file est vide }

Booleen est_vide(File f) {
if (f.tete == f.queue) return vrai; // enlever un élément
return faux; File defiler(File f) {

} /* pré-condition : file non vide !*/


if (est_vide(f)) {

// Valeur en tête de file printf("Erreur: file vide !\n");

Element tete(File f) { exit(-1);

/* pré-condition : file non vide ! */ }

if (est_vide(f)) { f.tete=(f.tete+1) % MAX_FILE;

printf("Erreur: file vide !\n"); return f;

exit(-1); }

}
return (f.tab)[(f.tete+1) % MAX_FILE];
}

Master IESE Structures de données avancées (2023-2024) 57

File chaînée

Tête de la file /* File chaînée en C */


File
pointée par tete
// type des éléments
Pointeur sur typedef int element;
cellule suivante

10 20 // type Cellule
typedef struct cellule {
element valeur;
struct cellule *suivant;
tete Pointeur } Cellule;
queue NULL
// type File
50 typedef struct {
struct cellule *tete;
Cellule contenant struct cellule *queue;
Queue de file
la valeur 30
pointée par queue } File;
Master IESE Structures de données avancées (2023-2024) 58

29
Spécification d'une File Chaînée
/* fichier "Cfile.h" */
#ifndef _FILE_CHAINEE
#define _FILE_CHAINEE

#include "Booleen.h"

// Définition du type File (implémentée par pointeurs)


typedef int Element; /* les éléments sont des int */

typedef struct cellule {


Element valeur;
struct cellule *suivant; Une cellule contient un
} Cellule;
élément et un pointeur sur
typedef struct { l'élément suivant
struct cellule *tete;
struct cellule *queue;
} File; type File : structure à deux
champs (pointeurs de tête et
// Déclaration des fonctions gérant la file
File pile_vide ();
de queue de file)
File enfiler ( File f, Element e );
File defiler ( File f );
Element tete ( File f );
Booleen est_vide ( File f );

#endif

Master IESE Structures de données avancées (2023-2024) 59

Réalisation d'une File Chaînée


File enfiler(File f, Element e) {
/* fichier "Cfile.c" */ Cellule * pc;
pc=(Cellule *)malloc(sizeof(Cellule));
#include "alloc.h" pc->valeur=e;
#include "Cfile.h" pc->suivant=NULL;
if (est_vide(f)
File file_vide() { f.tete=f.queue=pc;
File f; else f.queue=(f.queue)->suivant=pc;
f.tete=f.queue=NULL; return f;
return f; }
}

int est_vide(File f) { File defiler(File f) {


return (f.tete==NULL)&&(f.tete==NULL); /* pré-condition: file non vide ! */
} Cellule * pc;
if (est_vide(p)) {
Element tete(File f) { printf("Erreur: file vide !\n");
/* pré-condition: file non vide ! */ exit(-1);
if (est_vide(f)) { }
printf("Erreur: file vide !\n"); pc=f.tete;
exit(-1); f.tete=(f.tete)->suivant;
} free(pc);
return (f.tete)->valeur; if (f.tete==NULL) f.queue=NULL;
} return f;
}

Master IESE Structures de données avancées (2023-2024) 60

30
Complexité

• Les opérations sur les files sont toutes en O(1)

• Ceci est valable pour les deux représentations :


₋ file contiguë circulaire et file chaînée

Master IESE Structures de données avancées (2023-2024) 61

Applications d'une File


Exemples
• Gestion des travaux d’impression d’une imprimante :
• Cas d'une imprimante en réseau, où les tâches d'impressions
arrivent aléatoirement de n'importe quel ordinateur connecté.
Les tâches sont placées dans une file d'attente, ce qui permet
de les traiter selon leur ordre d'arrivée

• Ordonnanceur (dans les systèmes d’exploitation) :


• Maintenir une file de processus en attente d’un temps machine

• Parcours « en largeur » d’un arbre :


• (voir arbres)
Master IESE Structures de données avancées (2023-2024) 62

31
Exercices
1. Supposons que les contenus de la file F1 et la file F2 sont donnés. Quel est le contenu de la file F3 après
execution du code C ci-dessous ?. Le contenu de chaque file est affiché de sa tête (à gauche) à sa queue
(à droite). F1 : 42 30 41 31 19 20 25 14 10 11 12 15 F2 : 4 5 4 10 13
F3 = file_vide() ;
cpt = 0 ;
wile(( !est_vide(F1) et !est_vide(F2)) {
cpt += 1 ;
x = tete(F1) ;
F1 = defiler(F1) ;
y = tete(F2) ;
F2 = defiler(F2) ;
if (y == cpt) ;
F3  enfiler(F3, x) ;
}

2. [Enoncé TP3] Ecrire un programme C qui implémente une file (chaînée) d’entiers. Ce programme
affiche à l'utilisateur un menu avec les options suivantes :
1. enfiler un entier dans la file ;
2. défiler un entier de la file ;
3. taille de la file ;
4. tête de la file ;
5. afficher le contenu de la file ;
6. quitter le programme.
3. En utilisant les opérations de base sur les files, écrire une fonction C permettant de retourner le
minimum d’une file non vide d’entiers.
4. Ecrire un programme C pour inverser le contenu d’une file d’entiers. Indication : Utiliser une pile

Master IESE Structures de données avancées (2023-2024) 63

Les Listes
(Lists)

Master IESE 2023-2024

32
Notion de Liste (List) (1)
• Généralisation des piles et des files
₋ Structure linéaire dans laquelle les éléments peuvent être traités les uns à
la suite des autres
₋ Ajout ou retrait d'éléments n’importe où dans la liste
₋ Accès à n'importe quel élément

• Une liste est une suite finie, éventuellement vide, d'éléments de


même type repérés par leur rang dans la liste

• Chaque élément de la liste est rangé à une certaine place

• Exemple :
₋ une liste de 5 entiers L = <4, 1, 7, 3, 1> (place de rang 1 contient la valeur 4)
₋ une liste vide L2 = <>
Master IESE Structures de données avancées (2023-2024) 65

Notion de Liste (List) (2)

• Les éléments d'une liste sont donc ordonnés en


fonction de leur place

• Il existe une fonction notée succ qui, appliquée à


toute place sauf la dernière, fournit la place suivante

• Le nombre total d'éléments, et par conséquent de


places, est appelé longueur de la liste

• Une liste vide est d'une longueur égale 0

Master IESE Structures de données avancées (2023-2024) 66

33
Exemples de Liste

Liste vide

Accès à l'élément de rang 3


dans une liste à n éléments

Suppression de l'élément au rang 2


 longueur(liste) =n-1

Ajout de l'élément x au rang 2


 longueur(liste) =n+1

Master IESE Structures de données avancées (2023-2024) 67

Type Abstrait Liste (1)


Type Liste
Utilise Elément, Booléen, Place
Opérations
liste_vide :  Liste
longueur : Liste  Entier
insérer : Liste x Entier x Elément  Liste
supprimer : Liste x Entier  Liste
kème : Liste x Entier  Elément
accès : Liste x Entier  Place k = longueur(l) + 1
contenu : Liste x Place  Elément signifie ajout en fin de liste
succ : Liste x Place  Place
Préconditions
insérer(l,k,e) est-défini-ssi 1 ≤ k ≤ longueur(l)+1
supprimer(l,k) est-défini-ssi 1 ≤ k ≤ longueur(l)
kème(l,k) est-défini-ssi 1 ≤ k ≤ longueur(l)
accès(l,k) est-défini-ssi 1 ≤ k ≤ longueur(l)
succ(l,p) est-défini-ssi p ≠ accès(l,longueur(l))

Master IESE Structures de données avancées (2023-2024) 68

34
Type Abstrait Liste (2)
Axiomes
Soit, e : Elément, l, l' : Liste, k, j : Entier

si l = liste_vide alors longueur(l) = 0


sinon si l = insérer(l',k,e) alors longueur(l)=longueur(l')+1
sinon soit l = supprimer(l',k)alors longueur(l)=longueur(l')-1

si 1 ≤ j < k alors kème(insérer(l,k,e),j) = kème(l,j)


sinon si j = k alors kème(insérer(l,k,e),j) = e
sinon kème(insérer(l,k,e),j) = kème(l,j-1)
si 1 ≤ j < k alors kème(supprimer(l,k),j) = kème(l,j)
sinon kème(supprimer(l,k),j) = kème(l,j+1)

succ(l,accès(l,k)) = accès(l,k+1)
contenu(l,accès(l,k)) = kème(l,k)

si 1 ≤ k < j longueur(l) alors


contenu(l,accès(supprimer(l,j),k)) = contenu(l,accès(l,k))
si 1 ≤ k ≤ j < longueur(l) alors
contenu(l,accès(supprimer(l,j),k) = contenu(l,accès(l,k+1))
si 1 ≤ j < k 1+longueur(l) alors
contenu(l,accès(insérer(l,k,e),j) = contenu(l,accès(l,j))
si 1 ≤ k = j 1+longueur(l) alors
contenu(l,accès(insérer(l,k,e),j) = e
si 1 ≤ k < j 1+longueur(l) alors
contenu(l,accès(insérer(l,k,e),j) = contenu(l,accès(l,j-1))

Master IESE Structures de données avancées (2023-2024) 69

Extension Type Abstrait Liste


Extension Type Liste
Opérations
concaténer : Liste x Liste  Liste
est_présent : Liste x Elément  Booléen
Préconditions

Axiomes
Soit, e : Element, l, l' : Liste, k, j : Entier

longueur(concaténer(l,l')) = longueur(l) + longueur(l')

si k ≤ longueur(l)
alors kème(concaténer(l,l'),k)= kème(l,k)
sinon kème(concaténer(l,l'),k)= kème(l',k-longueur(l))

si longueur(l) = 0 alors est_présent(l,e) = faux


sinon si e = kème(l,1) alors est_présent(l,e) = vrai
sinon est_présent(supprimer(l,1),e)

Master IESE Structures de données avancées (2023-2024) 70

35
Opérations sur une Liste (1)

• liste_vide :  Liste
Opération d'initialisation ; la liste créée est vide

• longueur : Liste  Entier


Retourne le nombre d'éléments dans la liste

• insérer : Liste x Entier x Elément :  Liste


insérer(L,j,e): liste obtenue à partir de L en remplaçant la place j par une place
contenant e, sans modifier places précédentes et en décalant places suivantes

• supprimer : Liste x Entier :  Liste


supprimer(L,j): liste obtenue à partir de L en supprimant la place j et son
contenu, sans modifier places précédentes et en décalant places suivantes

Master IESE Structures de données avancées (2023-2024) 71

Opérations sur une Liste (2)


• kème : Liste x Entier  Elément
Fournit l'élément de rang donné dans une liste

• accès : Liste x Entier  Place


Connaître la place de rang donné : accès(L,k) est la place de rang k dans la liste L

• contenu : Liste x Place  Elément


Connaître l'élément d'une place donnée. contenu(L,p) = e : dans la liste L, la
place p contient l'élément e

• succ : Liste x Place  Place


Passer de place en place. succ(L,p) = p' : dans la liste L, la place qui succède à la
place p est la place p'. Opération indéfinie si place en entrée est la dernière place de
la liste

Master IESE Structures de données avancées (2023-2024) 72

36
Opérations Auxiliaires sur une Liste

• concaténer : Liste x Liste  Liste


Accroche deuxième liste en entrée à la fin de la première liste

• est_présent : Liste x Elément  Booléen


Teste si un élément figure dans une liste

Master IESE Structures de données avancées (2023-2024) 73

Représentation Contiguë d'une Liste


• Les éléments sont rangés les uns à côté des autres dans un
tableau :
• La ième case du tableau contient le ième élément de la liste
• Le rang est donc égal à la place ; ce sont des entiers

• La liste est représentée par une structure en langage C :


• Un tableau représente les éléments
• Un entier représente le nombre d'éléments dans la liste
• La longueur maximale, MAX_LISTE, de la liste doit être connue

Master IESE Structures de données avancées (2023-2024) 74

37
Liste Contiguë (Contiguous List)
/* Liste contiguë en C */

Liste // taille maximale liste


#define MAX_LISTE 10

0 1 2 3 4 5 6 7 8 9 // type des éléments


tab 10 6 30 40 50 typedef int Element;
taille 5
// type Place
Tableau de taille typedef int Place;
maximale = 10
La place du rang 3 // type Liste
contient la valeur 40 typedef struct {
Element tab[MAX_LISTE];
Nombre d'éléments int taille;
dans la liste } Liste;

Master IESE Structures de données avancées (2023-2024) 75

Spécification d'une Liste Contiguë


/* fichier "TListe.h" */
#ifndef _LISTE_TABLEAU
#define _LISTE_TABLEAU

// Définition du type liste (implémentée par tableau)


#define MAX_LISTE 100 /* taille maximale de la liste */
typedef int element; /* les éléments sont des int */

typedef int Place; /* la place = le rang (un int) */

typedef struct {
element tab[MAX_LISTE]; // les éléments de la liste
int taille; // nombre d'éléments dans la liste
} Liste;
type Liste : une
// Déclaration des fonctions gérant la liste
Liste liste_vide (void);
structure à deux champs
int longueur (Liste l);
Liste inserer (Liste l, int i, element e);
Liste supprimer (Liste l, int i);
element keme (Liste l, int k);

Place acces (Liste l, int i);


element contenu (Liste l, Place i);
Place succ (Liste l, Place i);

#endif

Master IESE Structures de données avancées (2023-2024) 76

38
Réalisation d'une Liste Contiguë (1)
Liste liste_vide(void) {
Liste l;
l.taille = 0;
return l;
}
Liste supprimer(Liste l, int i) {
// précondition : 0 ≤ i < longueur(l)
int longueur(Liste l) {
int r;
return l.taille;
if (i<0 || i>longueur(l)-1) { printf("Erreur : rang non
} valide !\n");
exit(-1);
Liste inserer(Liste l, int i, element e) { }
// précondition : longueur(l) = MAX_LISTE for (r = i; r<longueur(l)-1;; r++) l.tab[r] = l.tab[r+1];
// et 0 ≤ i < longueur(l)+1 (l.taille)--;
int r; return l;
if (longueur(l) == MAX_LISTE) { }
printf("Erreur : liste saturée !\n");
exit(-1); element keme(Liste l, int k) {
} // pas de sens que si 0 ≤ k ≤ longueur(l)-1
if (i<0 || i>longueur(l)) { if (k<0 || k>longueur(l)-1) {
printf("Erreur : rang non valide !\n"); printf("Erreur : rang non valide !\n");
exit(-1); exit(-1);
} }
for (r = longueur(l); r>i; r--) return l.tab[k];
l.tab[r] = l.tab[r-1]; }
l.tab[i] = e;
(l.taille)++;
return l;
}

Master IESE Structures de données avancées (2023-2024) 77

Réalisation d'une Liste Contiguë (2)


Place acces(Liste l, int i) {
// pas de sens que si 0<=i<=longueur(l)-1
if (i<0 || i>(longueur(l)-1)) {
printf("Erreur : rang non valide !\n");
exit(-1);
}
return i;
}

element contenu(Liste l, Place i) {


// pas de sens que si 0<=i<=longueur(l)-1
if (i<0 || i>(longueur(l)-1)) {
printf("Erreur : rang non valide !\n");
exit(-1);
}
return l.tab[i];
}

Place succ(Liste l, Place i) {


// pas de sens si i est la dernière place de la liste
if (i == (longueur(l)-1)) {
printf("Erreur : successeur de la dernière place !\n"); exit(-1);
}
return i+1;
}

Master IESE Structures de données avancées (2023-2024) 78

39
Représentation Chaînée d'une Liste

• Les éléments ne sont pas rangés les uns à côté des autres
₋ La place d'un élément est l'adresse d'une structure qui contient
l'élément ainsi que la place de l'élément suivant
₋ Utilisation de pointeurs pour chaîner entre eux les éléments
successifs

• La liste est représentée par un pointeur sur une structure


en langage C
₋ Une structure contient un élément de la liste et un pointeur sur
l'élément suivant
₋ La liste est déterminée par un pointeur sur son premier élément
₋ La liste vide est représentée par la constante prédéfinie NULL

Master IESE Structures de données avancées (2023-2024) 79

Liste Chaînée (Linked List)


/* Liste chaînée en C */
Liste Premier élément de la
liste pointée par L
// type des éléments
Pointeur sur typedef int element;
cellule suivante
// type Place
10 6
typedef struct cellule* Place;

// type Cellule
L Pointeur typedef struct cellule {
NULL element valeur;
struct cellule *suivant;
} Cellule;
Cellule contenant 50
la valeur 30 // type Liste
Dernier élément de typedef Cellule *Liste;
la liste
Master IESE Structures de données avancées (2023-2024) 80

40
Spécification d'une Liste Chaînée
/* fichier "CListe.h" */
#ifndef _LISTE_CHAINEE
#define _LISTE_CHAINEE

// Définition du type liste (implémentée par pointeurs)


typedef int element; /* les éléments sont des int */

typedef struct cellule *Place; /* la place = adresse cellule */

typedef struct cellule {


element valeur; // un éléments de la liste
struct cellule *suivant; // adresse cellule suivante
} Cellule;

typedef Cellule *Liste;


type Liste : un pointeur de
// Déclaration des fonctions gérant la liste Cellule
Liste liste_vide (void);
int longueur (Liste l);
Liste inserer (Liste l, int i, element e);
Liste supprimer (Liste l, int i);
element keme (Liste l, int k);

Place acces (Liste l, int i);


element contenu (Liste l, Place i);
Place succ (Liste l, Place i);

#endif

Master IESE Structures de données avancées (2023-2024) 81

Réalisation d'une Liste Chaînée (1)


else {
Liste liste_vide(void) { int j;
return NULL; Liste p=l;
} for (j=0; j<i-1; j++)
p=p->suivant;
int longueur(Liste l) { pc->suivant=p->suivant;
int taille=0; p->suivant=p;
Liste p=l; }
while (p) { return l;
taille++; }
p=p->suivant;
} Place acces(Liste l, int k) {
return taille; // pas de sens que si 0 ≤ k ≤ longueur(l)-1
} int i;
Place p;
Liste inserer(Liste l, int i, element e) { if (k<0 || k>=longueur(l)) {
// précondition :0 ≤ i < longueur(l)+1 printf("Erreur: rang invalide !\n");
if (i<0 || i>longueur(l)) { exit(-1);
printf("Erreur : rang non valide !\n"); }
exit(-1); if (k == 0)
} return l;
Liste pc = (Liste)malloc(sizeof(Cellule)); else {
pc->valeur=e; p=l;
pc->suivant=NULL; for(i=0; i<k; k++)
if (i==0){ p=p->suivant;
pc->suivant=l; return p;
l=pc; }
} }

Master IESE Structures de données avancées (2023-2024) 82

41
Réalisation d'une Liste Chaînée (2)
element contenu(Liste l, Place p) {
// pas de sens si longueur(l)=0 (liste vide)
if (longueur(l) == 0) {
printf("Erreur: liste vide !\n"); Liste supprimer(Liste l, int i) {

exit(-1); // précondition : 0 ≤ i < longueur(l)

} int j;

return p->valeur; Liste p;

} if (i<0 || i>longueur(l)+1) {
printf("Erreur: rang non valide!\n");

Place succ(Liste l, Place p) { exit(-1);

// pas de sens si p dernière place de liste }

if (p->suivant == NULL) { if (i == 0) {

printf("Erreur: suivant dernière place!\n"); p=l;

exit(-1); l=l->suivant;

} }

return p->suivant; else {

} Place q;
q=acces(l,i-1);

element keme(Liste l, int k) { p=succ(l,q);

// pas de sens que si 0 <= k <= longueur(l)-1 q->suivant=p->suivant;

if (k<0 || k>longueur(l)-1) { }

printf("Erreur : rang non valide !\n"); free(p);

exit(-1); return l;

} }

return contenu(l, acces(l,k));


}

Master IESE Structures de données avancées (2023-2024) 83

Remarques (1)

• Ajout au milieu d'une liste connaissant la place qui précède celle


où s'effectuera l'ajout
₋ ajouter : Liste x Place x Elément  Liste
₋ ajouter(L,p,e) : liste obtenue à partir de L en ajoutant une place contenant
l'élément e, juste après la place p

• Enlever un élément d'une liste connaissant sa place


₋ enlever : Liste x Place  Liste
₋ enlever(L,p) : liste obtenue à partir de L en supprimant la place p et son
contenu

Master IESE Structures de données avancées (2023-2024) 84

42
Remarques (2)

Liste ajouter(Liste l,
Place p, element e) { Liste enlever(Liste l, Place p) {
Liste pc; // p pointe élément à supprimer
pc=(Liste)malloc(sizeof(Cellule)); Place pred; //pred pointe avant p
if (pc == NULL) { if (p == l)
printf("Erreur: Problème de " l = succ(l,p);
"mémoire\n"); else {
exit(-1); pred=l;
while (succ(l,pred) != p)
}
pred = succ(l,pred);
pc->valeur = e;
pred->suivant = p->suivant;
pc->suivant = p->suivant;
}
p->suivant = pc free(p);
return l; return l;
} }

Master IESE Structures de données avancées (2023-2024) 85

Variantes de Listes Chaînées

• Liste avec tête fictive

• Liste chaînée circulaire

• Liste doublement chaînée

• Liste doublement chaînée circulaire

• Liste triée

Master IESE Structures de données avancées (2023-2024) 86

43
Liste avec Tête Fictive

• Eviter d'avoir un traitement particulier pour le cas de


la tête de liste (opérations d'insertion et de
suppression)
₋ Mettre en tête de liste une zone qui ne contient pas de
valeur et reste toujours en tête

Master IESE Structures de données avancées (2023-2024) 87

Liste Circulaire

• Le suivant du dernier élément de la liste est le


pointeur de tête

Master IESE Structures de données avancées (2023-2024) 88

44
Liste Doublement Chaînée

• Faciliter le parcours de la liste dans les deux sens


₋ Utiliser un double chaînage ; chaque place repérant à la
fois la place qui la précède et celle qui la suit

Master IESE Structures de données avancées (2023-2024) 89

Liste Triée

• Dans cette liste, il existe un ordre total sur les clés

• L’ordre des enregistrements dans la liste respecte l’ordre sur


les clés

10 15 20

Master IESE Structures de données avancées (2023-2024) 90

45
Complexité

Opération Représentation Représentation


contiguë chaînée
liste vide O(1) O(1)
ajout/suppression en tête O(n) O(1)
ajout/suppression générale O(n) O(n)
ajout/suppression en queue O(1) O(n)
accès O(1) O(n)

Où, n désigne le nombre d'éléments d'une liste

Master IESE Structures de données avancées (2023-2024) 91

Représentation par Curseurs d'une Liste

• Curseurs (ou faux pointeurs) utilisés dans le cas d'un


langage ne supportant pas les pointeurs :
₋ Par exemple, le langage Fortran

• La liste est représentée par une structure à trois champs


en langage C :
₋ Un tableau de couples (élément, suivant)
₋ Un entier (tete) désignant début de liste des éléments
₋ Un entier (dispo) désignant début de liste des cases libres
₋ Liste vide : tete  -1 et dispo  0

Master IESE Structures de données avancées (2023-2024) 92

46
Liste Chaînée par Curseurs
/* Liste chaînée en C */
Liste valeur suivant // taille maximale liste
0 10 -1 #define MAX_LISTE 7

1 20 5 // type des éléments


typedef int element;
Début de liste des
places occupées 2
// type Cellule
typedef struct cellule {
3 50 1 element valeur;
int suivant;
tete 3 4 } Cellule;

dispo 2 5 30 0 // type Liste


typedef struct {
6 Cellule cellules[MAX_LISTE];
int tete;
Début de liste int dispo;
Tableau de taille } Liste;
des places libres maximale = 7
Master IESE Structures de données avancées (2023-2024) 93

Exemples d'Applications d'une Liste

• Codage des polynômes :


• la liste d'entiers (0,1,0,-2,4) représente le polynôme à une
indéterminée X : 4 X4 – 2 X3 + X

• Codage des grands nombres

• Codage des matrices creuses

• Implémentation d’un logiciel de traitement de texte :


• Un texte est représenté par une liste de paragraphes

•…

Master IESE Structures de données avancées (2023-2024) 94

47
Exercices
1. Après avoir implémenté en C la structure de données Liste chaînée pour les entiers,
programmer une fonction main pour tester une liste d'entiers. Le programme
affiche à l'utilisateur un menu avec les options suivantes :
1. insérer un entier dans la liste ;
2. supprimer un élément de la liste ;
3. taille de la liste ;
4. consulter un élément de la liste ;
5. inverser le contenu de la liste ;
6. purger la liste (i.e., enlever les doublons de la liste) ;
7. afficher le contenu de la liste ;
8. quitter le programme.

2. [Enoncé TP4] : Application de la structure de données Liste : les polynômes creux


Il s’agit d’utiliser des listes chaînées pour représenter des polynômes en une
variable réelle x et à coefficients entiers. Tandis que les polynômes peuvent avoir
des degrés très élevés, ils sont creux dans le sens que seulement peu de
coefficients sont non nuls. (voir énoncé détaillé)

Master IESE Structures de données avancées (2023-2024) 95

48

Vous aimerez peut-être aussi