Transcript
Page 1: Cours Structures de données

CoursCoursStructures de Structures de

donnéesdonnéesTypes Abstraits de Types Abstraits de

DonnéesDonnées

Piles, Files & ListesPiles, Files & Listes

Page 2: Cours Structures de données

ObjectifsObjectifs

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

SpécificationSpécification ImplémentationImplémentation

Etudier les structures linéaires Etudier les structures linéaires classiquesclassiques

PilesPiles FilesFiles ListesListes

Page 3: Cours Structures de données

Types Abstraits Types Abstraits de Données de Données

(TADs)(TADs)Spécification & Spécification & ImplémentationImplémentation

Page 4: Cours Structures de données

Notion de Notion de Type Abstrait de Données (TAD)

La conception d’un algorithme est La conception d’un algorithme est indépendante de toute implantationindépendante de toute implantation

La représentation des données n'est pas La représentation des données n'est pas fixée ; fixée ; celles-ci sont considérées de manière celles-ci sont considérées de manière abstraiteabstraite

On s’intéresse à l’ensemble des opérations On s’intéresse à l’ensemble des opérations sur les données, et aux propriétés des sur les données, et aux propriétés des opérations, opérations, sans dire comment ces sans dire comment ces opérations sont réaliséesopérations sont réalisées

On parle de On parle de Type Abstrait de DonnéesType Abstrait de Données ( (TADTAD))

Page 5: Cours Structures de données

Définition d’un TADDéfinition d’un TAD Un TAD (Data Abstract TypeData Abstract Type) est un ensemble de valeurs muni ensemble de valeurs muni

d’opérations sur ces valeurs, sans faire référence à une d’opérations sur ces valeurs, sans faire référence à une implémentation particulière.implémentation particulière.

Exemples :Exemples :

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

Type Type booléenbooléen, ensemble de deux valeurs (, ensemble de deux valeurs (fauxfaux, , vraivrai) muni des ) muni des opérations : opérations : nonnon, , etet, , ouou

Un TAD est caractérisé par :Un TAD est caractérisé par :

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

Page 6: Cours Structures de données

Signature d’un TAD

Comporte :Comporte : Le nom du TAD ;Le nom du TAD ; Les noms des types des objets utilisés par le Les noms des types des objets utilisés par le

TAD ;TAD ; Pour chaque opération, l’énoncé des types Pour chaque opération, l’énoncé des types

des objets qu’elle reçoit et qu’elle renvoie.des objets qu’elle reçoit et qu’elle renvoie.

Décrite par les paragraphes :Décrite par les paragraphes : TypeType UtiliseUtilise OpérationsOpérations

Page 7: Cours Structures de données

Signature d’un TADExemple : TAD Booléen

Type Type BooléenBooléen

OpérationsOpérationsvraivrai : : Booléen Booléen

fauxfaux : : Booléen Booléen

non non  : Booléen : Booléen Booléen Booléen

et et  : Booléen x Booléen : Booléen x Booléen Booléen Booléen

ouou : Booléen x Booléen : Booléen x Booléen Booléen Booléen

Nom du TAD

Nom de l'opération

Deux arguments de type BooléenType valeur

de retour

Page 8: Cours Structures de données

Sémantique d’un TAD Précise :Précise :

Les domaines de définition (ou Les domaines de définition (ou d’application) des opérations ;d’application) des opérations ;

Les propriétés des opérations.Les propriétés des opérations.

Décrite par les paragraphes :Décrite par les paragraphes : PréconditionsPréconditions AxiomesAxiomes

On parle d’un On parle d’un Type Abstrait AlgébriqueType Abstrait Algébrique ((TAATAA) lorsque la sémantique est définie ) lorsque la sémantique est définie par un système d’équationspar un système d’équations

Page 9: Cours Structures de données

Exemple 1 de TAD(TAD Booléen)

Type Type BooléenBooléenOpérationsOpérations

vraivrai : : Booléen Booléenfauxfaux : : Booléen Booléennon non  : Booléen : Booléen Booléen Booléenet et  : Booléen : Booléen ×× Booléen Booléen Booléen Booléenouou : Booléen : Booléen ×× Booléen Booléen Booléen Booléen

PréconditionsPréconditions

AxiomesAxiomesSoit, a, b : Soit, a, b : BooléenBooléennon(vrai) = fauxnon(vrai) = fauxnon(non(a)) = anon(non(a)) = avrai et a = avrai et a = afaux et a = fauxfaux et a = fauxa ou b = non(non(a) et non(b))a ou b = non(non(a) et non(b))

Aucune précondit

ion

Page 10: Cours Structures de données

Exemple 2 de TAD(TAD Vecteur)

TypeType Vecteur VecteurUtiliseUtilise Entier, Elément Entier, Elément Opérations Opérations

vectvect : Entier : Entier Vecteur Vecteurchanger_ièmechanger_ième : Vecteur x Entier x Elément : Vecteur x Entier x Elément Vecteur Vecteurièmeième : Vecteur x Entier : Vecteur x Entier Elément Elémenttailletaille : Vecteur : Vecteur Entier Entier

Préconditions Préconditions vect(i) vect(i) est_défini_ssi est_défini_ssi i ≥ 0i ≥ 0ième(v,i) ième(v,i) est_défini_ssi est_défini_ssi 0 ≤ i < taille(v)0 ≤ i < taille(v)changer_ième(v,i,e) changer_ième(v,i,e) est_défini_ssiest_défini_ssi 0 ≤ i < taille(v) 0 ≤ i < taille(v)

AxiomesAxiomesSoit, i, j : Entier, e : Elément, v : VecteurSoit, i, j : Entier, e : Elément, v : Vecteursisi 0 ≤ i < taille(v) 0 ≤ i < taille(v) alorsalors ième(changer_ième(v,i,e),i) = e ième(changer_ième(v,i,e),i) = esisi 0 ≤ i < taille(v) 0 ≤ i < taille(v) etet 0 ≤ j < taille(v) 0 ≤ j < taille(v) etet i ≠ j i ≠ j

alorsalors ième(changer_ième(v,i,e),j) = ième(v,j) ième(changer_ième(v,i,e),j) = ième(v,j)taille(vect(i)) = itaille(vect(i)) = itaille(changer_ième(v,i,e)) = taille(v)taille(changer_ième(v,i,e)) = taille(v)

Page 11: Cours Structures de données

OpérateursOpérateurs Trois catégories d'opérateurs (ou de Trois catégories d'opérateurs (ou de

primitives) :primitives) :

ConstructeursConstructeurs : : type spécifié apparaît, uniquement, comme résultat ;

Observateurs Observateurs :: type spécifié apparaît, uniquement, comme argument ;

Transformateurs :Transformateurs : type spécifié apparaît, à la fois, comme argument et comme résultat ;

Constante :Constante : opérateur sans argument

Page 12: Cours Structures de données

Opérations PartiellesOpé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 :Exemple : Opérations Opérations ième et et changer_ième du TAD du TAD VecteurVecteur

Page 13: Cours Structures de données

Réutilisation des TADsRé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 Types Entier Entier et et ElémentElément utilisés par le TAD utilisés par le TAD VecteurVecteur

Page 14: Cours Structures de données

Choix des AxiomesChoix des Axiomes

Le système d'axiomes doit être :

non contradictoire (consistance) : le résultat de chaque observateur est-il unique ?

complet (complétude suffisante) : Peut-on déduire des axiomes le résultat de chaque observateur sur son domaine de définition ?

Page 15: Cours Structures de données

Notion de Structure de Notion de Structure de DonnéesDonnées

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

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

Composée d’un algorithme pour chaque Composée d’un algorithme pour chaque opération, plus éventuellement des données opération, plus éventuellement des données spécifiques à la structure pour sa gestionspécifiques à la structure pour sa gestion

Un même TAD peut donner lieu à plusieurs Un même TAD peut donner lieu à plusieurs structures de données, avec des structures de données, avec des performances différentesperformances différentes

Page 16: Cours Structures de données

Implémentation d’un Implémentation d’un TADTAD

Pour implémenter un TAD : Déclarer la structure de données retenue pour représenter le Déclarer la structure de données retenue pour représenter le

TAD : TAD : L’interfaceL’interface Définir les opérations primitives dans un langage particulier : Définir les opérations primitives dans un langage particulier : La La

réalisationré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

Page 17: Cours Structures de données

Implémentation d’un Implémentation d’un TAD en CTAD en C

Utiliser la programmation modulaire (Utiliser la programmation modulaire (voir TPsvoir TPs) :) : Programme découpé en plusieurs fichiers, même de petites tailles Programme découpé en plusieurs fichiers, même de petites tailles

((réutilisabilité, lisibilité, etc.)réutilisabilité, lisibilité, etc.) Chaque composante logique (Chaque composante logique (un moduleun module) regroupe les fonctions et types ) regroupe les fonctions et types

autour d'un même thème. autour d'un même thème.

Pour chaque module Pour chaque module tructruc, créer deux fichiers : , créer deux fichiers : fichier fichier truc.h :truc.h : l'interfacel'interface ((la partie publiquela partie publique) ; contient la ) ; contient la spécificationspécification de de

la structure ;la structure ; fichier fichier truc.c :truc.c : la définitionla définition ( (la partie privéela partie privée) ; contient ) ; contient la réalisationla réalisation des des

opérations fournies par la structure. Il contient au début l'inclusion du fichier opérations fournies par la structure. Il contient au début l'inclusion du fichier truc.htruc.h

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

Un module C implémente un TAD :Un module C implémente un TAD : L'encapsulation :L'encapsulation : détails d'implémentation cachés ; l'interface est la partie ; l'interface est la partie

visible à un utilisateurvisible à un utilisateur La réutilisation :La réutilisation : placer placer les deux fichiers du module dans le répertoire où les deux fichiers du module dans le répertoire où

l'on développe l'application.l'on développe l'application.

Page 18: Cours Structures de données

Implémentation d’un TADImplémentation d’un TADExemple : TAD BooléenExemple : TAD Booléen

/* fichier Booleen.h *//* fichier Booleen.h */

#ifndef _BOOLEEN#ifndef _BOOLEEN#define _BOOLEEN#define _BOOLEEN

typedef enum (faux,vrai) Booleen; typedef enum (faux,vrai) Booleen;

Booleen et(Booleen x, Booleen y); Booleen et(Booleen x, Booleen y); Booleen ou(Booleen x, Booleen y); Booleen ou(Booleen x, Booleen y); Booleen non(Booleen x) ; Booleen non(Booleen x) ;

#endif#endif

/* fichier Booleen.c *//* fichier Booleen.c */

#include "Booleen.h"#include "Booleen.h"

Booleen et(Booleen x, Booleen y) {Booleen et(Booleen x, Booleen y) { if (x == faux) if (x == faux) return faux; return faux; else return y;else return y;} }

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

Booleen non(Booleen x) {Booleen non(Booleen x) { if (x == vrai) if (x == vrai) return faux; return faux; else return vrai;else return vrai;}}

L'interface (partie

publique)

La définition

(partie privée)

Page 19: Cours Structures de données

Structures de Structures de Données Données LinéairesLinéaires

Piles, Files & listesPiles, Files & listes

Page 20: Cours Structures de données

ObjectifsObjectifs

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

Une structure linéaire est un arrangement Une structure linéaire est un arrangement linéaire d'éléments liés par la relation successeurlinéaire d'éléments liés par la relation successeur Exemple :Exemple : Un tableau ( Un tableau (la relation successeur est implicitela relation successeur est implicite). ).

Pour chaque structure, on présente :Pour chaque structure, on présente : une définition abstraite ;une définition abstraite ; les différentes représentations en mémoire ; les différentes représentations en mémoire ; une implémentation en langage C ; une implémentation en langage C ; quelques applications.quelques applications.

Page 21: Cours Structures de données

Les Piles (Stacks)Les Piles (Stacks)

Page 22: Cours Structures de données

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

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

Une pile est une structure linéaire permettant Une pile est une structure linéaire permettant de stocker et de restaurer des données selon de stocker et de restaurer des données selon un un ordre LIFOordre LIFO ( (Last In, First OutLast In, First Out ouou « dernier entré, « dernier entré, premier sorti ») premier sorti »)

Dans une pile :Dans une pile : Les insertions (Les insertions (empilementsempilements) et les suppressions ) et les suppressions

((dépilementsdépilements) sont restreintes à une extrémité appelée ) sont restreintes à une extrémité appelée sommetsommet de la pile. de la pile.

Page 23: Cours Structures de données

Exemple de PileExemple de Pile

sommet D sommet C C sommet C sommet E E E E sommet A A A A A sommet B B B B B B

Empiler B Empiler

A Empiler E Empiler

C Empiler D

Dépiler D

Page 24: Cours Structures de données

Ajouter dans cet ordreAjouter dans cet ordre A EB D FCA B C D E F

Pile

Exemple de Pile (1)Exemple de Pile (1)

Page 25: Cours Structures de données

A

B

C

D

E

F

Pile

Exemple de Pile (2)Exemple de Pile (2)

Page 26: Cours Structures de données

Type Abstrait Pile Type Abstrait Pile TypeType Pile PileUtiliseUtilise Elément, Booléen Elément, BooléenOpérationsOpérations

pile_vide pile_vide  : : Pile Pileest_vide est_vide  : Pile : Pile Booléen Booléenempiler empiler  : Pile x Elément : Pile x Elément Pile Piledépiler dépiler  : Pile : Pile Pile Pilesommet sommet  : Pile : Pile Elément Elément

PréconditionsPréconditionsdépiler(p) dépiler(p) est-défini-ssiest-défini-ssi est_vide(p) = est_vide(p) = fauxfauxsommet(p) sommet(p) est-défini-ssiest-défini-ssi est_vide(p) = est_vide(p) = fauxfaux

Axiomes Axiomes Soit, e : Element, p : PileSoit, e : Element, p : Pileest_vide(pile_vide) = est_vide(pile_vide) = vraivraiest_vide(empiler(p,e)) = est_vide(empiler(p,e)) = fauxfauxdépiler(empiler(p,e)) = p dépiler(empiler(p,e)) = p sommet(empiler(p,e)) = e sommet(empiler(p,e)) = e

Page 27: Cours Structures de données

Opérations sur une PileOpérations sur une Pile pile_vide : pile_vide : Pile Pile

opération d'initialisation ; opération d'initialisation ; la pile créée est videla pile créée est vide

est_vide : Pile est_vide : Pile Booléen Booléen teste si pile vide ou nonteste si pile vide ou non

sommet : Pile sommet : Pile Elément Elément permet de consulter l'élément situé au sommet ; permet de consulter l'élément situé au sommet ; n'a pas de n'a pas de

sens si pile videsens si pile vide

empiler : Pile x Elément empiler : Pile x Elément Pile Pile ajoute un élément dans la pileajoute un élément dans la pile

dépiler : Pile dépiler : Pile Pile Pile enlève l'élément situé au sommet de la pile ; enlève l'élément situé au sommet de la pile ; n'a pas de n'a pas de

sens si pile videsens si pile vide

Page 28: Cours Structures de données

Représentation d'une Représentation d'une PilePile

Représentation contiguë (Représentation contiguë (par tableaupar 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) :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

Page 29: Cours Structures de données

Pile ContiguëPile Contiguë

66

55

44

1010 33

2020 22

55 11

5050 00

3sommet

elements

Pile

/* Pile contiguë en C */

// taille maximale pile#define MAX_PILE 7

// type des élémentstypedef int Element;

// type Piletypedef struct { Element elements[MAX_PILE]; int sommet; } Pile;Tableau de

taille maximale 7

Page 30: Cours Structures de données

Spécification d'une Pile Spécification d'une Pile ContiguëContiguë

/* fichier "Tpile.h" *//* fichier "Tpile.h" */#ifndef _PILE_TABLEAU#ifndef _PILE_TABLEAU#define _PILE_TABLEAU#define _PILE_TABLEAU

#include "Booleen.h"#include "Booleen.h"

// Définition du type Pile (implémentée par un tableau) // Définition du type Pile (implémentée par un tableau) #define MAX_PILE 7 #define MAX_PILE 7 /* taille maximale d'une pile *//* taille maximale d'une pile */typedef int Element; typedef int Element; /* les éléments sont des /* les éléments sont des intint */ */

typedef struct {typedef struct { Element elements[MAX_PILE]; Element elements[MAX_PILE]; /* les éléments de la pile *//* les éléments de la pile */ int sommet; int sommet; /* position du sommet *//* position du sommet */} Pile;} Pile;

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

#endif#endif

type Pile : une type Pile : une structure à deux structure à deux

champschamps

Page 31: Cours Structures de données

/* fichier "Tpile.c" *//* fichier "Tpile.c" */

#include "Tpile.h"#include "Tpile.h"

// Définition des fonctions gérant la pile // Définition des fonctions gérant la pile // initialiser une nouvelle pile// initialiser une nouvelle pile Pile pile_vide() {Pile pile_vide() { Pile p; Pile p; p.sommet = -1;p.sommet = -1; return p;return p;}} // tester si la pile est vide// tester si la pile est videBooleen est_vide(Pile p) {Booleen est_vide(Pile p) { if (p.sommet == -1) return vrai;if (p.sommet == -1) return vrai; return faux;return faux;}}

// Valeur du sommet de pile// Valeur du sommet de pileElement sommet(Pile p) {Element sommet(Pile p) {/* pré-condition : pile non vide ! *//* pré-condition : pile non vide ! */ if (est_vide(p)) { if (est_vide(p)) { printf("Erreur: pile vide !\n"); printf("Erreur: pile vide !\n"); exit(-1);exit(-1); }} return (p.elements)[p.sommet];return (p.elements)[p.sommet];}}

// ajout d'un élément// ajout d'un élémentPile empiler(Pile p, Element e) {Pile empiler(Pile p, Element e) { if (p.sommet >= MAX_PILE-1) {if (p.sommet >= MAX_PILE-1) { printf("Erreur : pile pleine !\n"); printf("Erreur : pile pleine !\n"); exit(-1);exit(-1); }} (p.sommet)++;(p.sommet)++; (p.elements)[p.sommet] = e;(p.elements)[p.sommet] = e; return p;return p;}}

// enlever un élément// enlever un élémentPile depiler(Pile p) {Pile depiler(Pile p) {/* pré-condition : pile non vide !*//* pré-condition : pile non vide !*/ if (est_vide(p)) {if (est_vide(p)) { printf("Erreur: pile vide !\n"); printf("Erreur: pile vide !\n"); exit(-1);exit(-1); }} p.sommet--;p.sommet--; return p;return p;}}

Réalisation d'une Pile Réalisation d'une Pile ContiguëContiguë

Page 32: Cours Structures de données

Exemple d'Utilisation d'une Pile Exemple d'Utilisation d'une Pile ContiguëContiguë

/* fichier "UTpile.c" *//* fichier "UTpile.c" */ #include <stdio.h>#include <stdio.h>#include "Tpile.h"#include "Tpile.h"

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

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

Page 33: Cours Structures de données

Pile chaînéePile chaînée

p

Pile

10 20

50

5

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

// type des élémentstypedef int element;

// type Celluletypedef struct cellule { element valeur; struct cellule *suivant; } Cellule;

// type Piletypedef Cellule *Pile;

Sommet de la pile pointée

par p

Cellule contenant la

valeur 5Pointeur sur

cellule suivante

Pointeur NULL

Page 34: Cours Structures de données

Spécification d'une Pile Spécification d'une Pile ChaînéeChaînée/* fichier "Cpile.h" *//* fichier "Cpile.h" */

#ifndef _PILE_CHAINEE#ifndef _PILE_CHAINEE#define _PILE_CHAINEE#define _PILE_CHAINEE

#include "Booleen.h"#include "Booleen.h"

// Définition du type Pile (implémentée par pointeurs)// Définition du type Pile (implémentée par pointeurs)typedef int Element; typedef int Element; /* les éléments sont des /* les éléments sont des intint */ */

typedef struct cellule { typedef struct cellule { Element valeur; Element valeur; struct cellule *suivant;struct cellule *suivant;} Cellule;} Cellule;

typedef Cellule *Pile;typedef Cellule *Pile;

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

#endif#endif

type Pile : un type Pile : un pointeur de pointeur de

CelluleCellule

Une cellule Une cellule contient un contient un

élément et un élément et un pointeur sur pointeur sur

l'élément suivantl'élément suivant

Page 35: Cours Structures de données

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

/* fichier "Cpile.c" *//* fichier "Cpile.c" */

#include "alloc.h"#include "alloc.h"#include "Cpile.h"#include "Cpile.h"

Pile pile_vide(void) { Pile pile_vide(void) { return NULL;return NULL;}}

int est_vide(Pile p) { int est_vide(Pile p) { return (p == NULL); return (p == NULL); }}

Element sommet(Pile p) {Element sommet(Pile p) {/* pré-condition: pile non vide ! *//* pré-condition: pile non vide ! */ if (est_vide(p)) { if (est_vide(p)) { printf("Erreur: pile vide !\n"); printf("Erreur: pile vide !\n"); exit(-1);exit(-1); }} return p->valeur;return p->valeur;}}

Pile empiler(Pile p, Element e) {Pile empiler(Pile p, Element e) { Cellule * pc;Cellule * pc; pc=(Cellule *)malloc(sizeof(Cellule));pc=(Cellule *)malloc(sizeof(Cellule)); pc->valeur=e;pc->valeur=e; pc->suivant=p;pc->suivant=p; return pc;return pc;}}

Pile depiler(Pile p) {Pile depiler(Pile p) {/* pré-condition: pile non vide ! *//* pré-condition: pile non vide ! */ Cellule * pc = p;Cellule * pc = p; if (est_vide(p)) {if (est_vide(p)) { printf("Erreur: pile vide !\n");printf("Erreur: pile vide !\n"); exit(-1);exit(-1); }} p=p->suivant; p=p->suivant; free(pc);free(pc); return p;return p;}}

allouer un espace

mémoire pour une nouvelle

cellule

libérer l'espace mémoire

occupé par la cellule

Page 36: Cours Structures de données

Exemple d'Utilisation d'une Pile Exemple d'Utilisation d'une Pile ChaînéeChaînée

/* fichier "UCpile.c" *//* fichier "UCpile.c" */ #include <stdio.h>#include <stdio.h>#include "Cpile.h"#include "Cpile.h"

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

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

Page 37: Cours Structures de données

ComplexitéComplexité

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

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

Page 38: Cours Structures de données

Applications d'une PileApplications d'une PileExemples (1)Exemples (1)

Vérification du bon équilibrage d’une expression Vérification du bon équilibrage d’une expression parenthèsée : parenthèsée : Pour vérifier qu'une expression parenthèsée est équilibré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 ouvrante on l'empile et à chaque rencontre d'une parenthèse fermante on dépile ;chaque rencontre d'une parenthèse fermante on dépile ;

Evaluation des expressions arithmétiques postfixées Evaluation des expressions arithmétiques postfixées ((expressions en notation polonaise inverseexpressions en notation polonaise inverse) :) : Pour évaluer une telle expression, on applique chaque opérateur 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 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 dans laquelle les opérandes sont empilés, alors que les opérateurs dépilent deux éléments, effectuent l'opération et opérateurs dépilent deux éléments, effectuent l'opération et empilent le résultat. Par exemple, l'expression postfixée empilent le résultat. Par exemple, l'expression postfixée 2 3 5 * 2 3 5 * + 1 –+ 1 – s'évalue comme suit : s'évalue comme suit : ((2 (3 5 *) +) 1 –) = 16((2 (3 5 *) +) 1 –) = 16 ; ;

Conversion d’une expression en notation infixe Conversion d’une expression en notation infixe ((parenthèséeparenthèsée) en notation postfixée ;) en notation postfixée ;

Page 39: Cours Structures de données

Applications d'une PileApplications d'une PileExemples (2)Exemples (2)

Gestion par le compilateur des appels de Gestion par le compilateur des appels de fonctions :fonctions : les paramètres, l’adresse de retour et les variables les paramètres, l’adresse de retour et les variables

locales sont stockées dans la pile de l’applicationlocales sont stockées dans la pile de l’application

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

Parcours « en profondeur » de structures Parcours « en profondeur » de structures d'arbresd'arbres ( (voir chapitre arbresvoir chapitre arbres) ;) ;

Page 40: Cours Structures de données

Les Files Les Files (Queues)(Queues)

Page 41: Cours Structures de données

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

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

Une file est une structure linéaire permettant de Une file est une structure linéaire permettant de stocker et de restaurer des données selon stocker et de restaurer des données selon un ordre un ordre FIFOFIFO ( (First In, First OutFirst In, First Out ouou « premier entré, premier « premier entré, premier sorti ») sorti »)

Dans une file :Dans une file : Les insertions (Les insertions (enfilementsenfilements) se font à une extrémité appelée ) se font à une extrémité appelée

queuequeue de la file et les suppressions ( de la file et les suppressions (défilementsdéfilements) se font à ) se font à l'autre extrémité appelée l'autre extrémité appelée têtetête de la file de la file

Page 42: Cours Structures de données

Exemple de FileExemple de File

queue queue D queue queue C C D queue E E E C

queue A A A A E tête B tête B tête B tête B tête B tête A

Enfiler B Enfiler

A Enfiler E Enfiler

C Enfiler D

Défiler B

Page 43: Cours Structures de données

Ajouter dans cet ordreAjouter dans cet ordre A EB D FCA B C D E F

Exemple de File (1)Exemple de File (1)

File

Page 44: Cours Structures de données

A EB D FC

Exemple de File (2)Exemple de File (2)

File

Page 45: Cours Structures de données

Type Abstrait File Type Abstrait File TypeType File FileUtiliseUtilise Elément, Booléen Elément, BooléenOpérationsOpérations

file_vide file_vide  : : File Fileest_vide est_vide  : File : File Booléen Booléenenfiler enfiler  : File x Elément : File x Elément File Filedéfiler défiler  : File : File File Filetête tête  : : Elément Elément

PréconditionsPréconditionsdéfiler(f) défiler(f) est-défini-ssiest-défini-ssi est_vide(f) = est_vide(f) = fauxfauxtête(f) tête(f) est-défini-ssiest-défini-ssi est_vide(f) = est_vide(f) = fauxfaux

Axiomes Axiomes Soit, e : Element, f : FileSoit, e : Element, f : Fileest_vide(file_vide) = est_vide(file_vide) = vraivraiest_vide(enfiler(f,e)) = est_vide(enfiler(f,e)) = fauxfauxsisi est_vide(f) = est_vide(f) = vraivrai alorsalors tête(enfiler(f,e)) = e tête(enfiler(f,e)) = esisi est_vide(f) = est_vide(f) = fauxfaux alorsalors tête(enfiler(f,e)) = tête(f) tête(enfiler(f,e)) = tête(f)sisi est_vide(f) = est_vide(f) = vraivrai alorsalors défiler(enfiler(f,e)) = file_vide défiler(enfiler(f,e)) = file_videsi si est_vide(f) = est_vide(f) = fauxfaux alorsalors défiler(enfiler(f,e)) = enfiler(défiler(f),e) défiler(enfiler(f,e)) = enfiler(défiler(f),e)

Page 46: Cours Structures de données

Opérations sur une FileOpérations sur une File file_vide : file_vide : File File

opération d'initialisation ; opération d'initialisation ; la file créée est videla file créée est vide

est_vide : File est_vide : File Booléen Booléen teste si file vide ou nonteste si file vide ou non

tête : File tête : File Elément Elément permet de consulter l'élément situé en tête de file ; permet de consulter l'élément situé en tête de file ; n'a pas n'a pas

de sens si file videde sens si file vide

enfiler : File x Elément enfiler : File x Elément File File ajoute un élément dans la fileajoute un élément dans la file

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

videvide

Page 47: Cours Structures de données

Représentation d'une Représentation d'une FileFile

Représentation contiguë (Représentation contiguë (par tableaupar 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) :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

Page 48: Cours Structures de données

Représentation Contiguë Représentation Contiguë d'une Filed'une File

(par tableau simple) (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 tête queue queue -1 -1

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

Page 49: Cours Structures de données

Représentation Contiguë Représentation Contiguë d'une Filed'une File

(par tableau simple) (1) (par tableau simple) (1)

00 11 22 33 44 55 66 77 88 99

tab

tete

queue

6

6

00 11 22 33 44 55 66 77 88 99

1100

2200

3300

4400

5500

tab

tete

queue

1

6

00 11 22 33 44 55 66 77 88 99

tab

tete

queue

-1

-1

00 11 22 33 44 55 66 77 88 99

55 22 1100

2200

3300

4400

5500

tab

tete

queue

-1

6File initialement vide de taille

maximale = 10(1)

(3) (4)

File après ajout de 5, 2, 10, 20,

30, 40 et 50(2)

File après suppression de 5

et 2

File après suppression de 10, 20, 30, 40 et

50

Page 50: Cours Structures de données

Représentation Contiguë Représentation Contiguë d'une Filed'une File

(par tableau simple) (2) (par tableau simple) (2)00 11 22 33 44 55 66 77 88 99

tab

tete

queue

6

6

(5)File vide

00 11 22 33 44 55 66 77 88 99

55 1155

1100

tab

tete

queue

6

9 File après ajout de

5, 15 et 10(6)

00 11 22 33 44 55 66 77 88 99

1100

tab

tete

queue

8

9 On ne peut plus ajouter dans la

file !!(8)

00 11 22 33 44 55 66 77 88 99

1100

tab

tete

queue

8

9 File après suppression 5

et 15(7)

Page 51: Cours Structures de données

File ContiguëFile Contiguë/* File contiguë en C */

// taille maximale file#define MAX_FILE 10

// type des élémentstypedef int Element;

// type Filetypedef struct { Element tab[MAX_FILE]; int tete; int queue;} File;

00 11 22 33 44 55 66 77 88 99

1100

2200

3300

4400

5500

tab

tete

queue

1

6

File

Tableau de taille

maximale 10Position qui

précède le premier élément de la file

Position du dernier élément

de la file

Page 52: Cours Structures de données

Spécification d'une File Spécification d'une File ContiguëContiguë/* fichier "Tfile.h" *//* fichier "Tfile.h" */

#ifndef _FILE_TABLEAU#ifndef _FILE_TABLEAU#define _FILE_TABLEAU#define _FILE_TABLEAU

#include "Booleen.h"#include "Booleen.h"

// Définition du type File (implémentée par un tableau simple) // Définition du type File (implémentée par un tableau simple) #define MAX_FILE 10 #define MAX_FILE 10 /* taille maximale d'une file *//* taille maximale d'une file */typedef int Element; typedef int Element; /* les éléments sont des /* les éléments sont des intint */ */

typedef struct {typedef struct { Element tab[MAX_FILE]; Element tab[MAX_FILE]; /* les éléments de la file *//* les éléments de la file */ int tete; int tete; /* position précédant premier élément *//* position précédant premier élément */ int queue; int queue; /* position dernier élément */ /* position dernier élément */ } File;} File;

// Déclaration des fonctions gérant la pile// Déclaration des fonctions gérant la pileFile file_vide ();File file_vide ();File enfiler ( File f, Element e );File enfiler ( File f, Element e );File defiler ( File f );File defiler ( File f );Element tete ( File f );Element tete ( File f );Booleen est_vide ( File f );Booleen est_vide ( File f );

#endif#endif

type File : une type File : une structure à trois structure à trois

champschamps

Page 53: Cours Structures de données

/* fichier "Tfile.c" *//* fichier "Tfile.c" */

#include "Tfile.h"#include "Tfile.h"

// Définition des fonctions gérant la file // Définition des fonctions gérant la file // initialiser une nouvelle file// initialiser une nouvelle file File file_vide() {File file_vide() { File f; File f; f.queue = f.tete = -1;f.queue = f.tete = -1; return f;return f;}} // tester si la file est vide// tester si la file est videBooleen est_vide(File f) {Booleen est_vide(File f) { if (f.tete == f.queue) return vrai;if (f.tete == f.queue) return vrai; return faux;return faux;}}

// Valeur en tête de file// Valeur en tête de fileElement tete(File f) {Element tete(File f) {/* pré-condition : file non vide ! *//* pré-condition : file non vide ! */ if (est_vide(f)) { if (est_vide(f)) { printf("Erreur: file vide !\n"); printf("Erreur: file vide !\n"); exit(-1);exit(-1); }} return (f.tab)[f.tete+1];return (f.tab)[f.tete+1];}}

// ajout d'un élément// ajout d'un élémentFile enfiler(File f, Element e) {File enfiler(File f, Element e) { if (f.queue == MAX_FILE-1) {if (f.queue == MAX_FILE-1) { printf("Erreur: on ne peut ajouter !\n"); printf("Erreur: on ne peut ajouter !\n"); exit(-1);exit(-1); }} (f.queue)++;(f.queue)++; (f.tab)[f.queue] = e;(f.tab)[f.queue] = e; return f;return f;}}

// enlever un élément// enlever un élémentFile defiler(File f) {File defiler(File f) {/* pré-condition : file non vide !*//* pré-condition : file non vide !*/ if (est_vide(f)) {if (est_vide(f)) { printf("Erreur: file vide !\n"); printf("Erreur: file vide !\n"); exit(-1);exit(-1); }} f.tete++;f.tete++; return f;return f;}}

Réalisation d'une File Réalisation d'une File ContiguëContiguë

Page 54: Cours Structures de données

Représentation Contiguë Représentation Contiguë d'une Filed'une File

(par tableau simple avec (par tableau simple avec décalage)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

Page 55: Cours Structures de données

Représentation Contiguë Représentation Contiguë d'une Filed'une File

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

00 11 22 33 44 55 66 77 88 99

tab

tete

queue

-1

-1

00 11 22 33 44 55 66 77 88 99

1100

2200

3300

4400

5500

tab

tete

queue

-1

4

00 11 22 33 44 55 66 77 88 99

tab

tete

queue

-1

-1

00 11 22 33 44 55 66 77 88 99

55 22 1100

2200

3300

4400

5500

tab

tete

queue

-1

6File initialement vide de taille

maximale = 10(1)

(3) (4)

File après ajout de 5, 2, 10, 20,

30, 40 et 50(2)

File après suppression de 5

et 2

File après suppression de 10, 20, 30, 40 et

50

Page 56: Cours Structures de données

Représentation Contiguë Représentation Contiguë d'une Filed'une File

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

00 11 22 33 44 55 66 77 88 99

tab

tete

queue

-1

-1

(5)File vide

00 11 22 33 44 55 66 77 88 99

55 1155

1100

tab

tete

queue

-1

2 File après ajout de

5, 15 et 10(6)

00 11 22 33 44 55 66 77 88 99

1100

55 66 2200

88 3355

2255

3333

44 8800

tab

tete

queue

-1

9Après ajout de 5, 6, 20, 8, 35, 25, 33, 4 et 80, File

pleine!!(8)

00 11 22 33 44 55 66 77 88 99

1100

tab

tete

queue

-1

0 File après suppression 5

et 15(7)

Page 57: Cours Structures de données

Représentation Contiguë Représentation Contiguë d'une Filed'une File

(Par tableau circulaire) (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

Page 58: Cours Structures de données

File Contiguë CirculaireFile Contiguë Circulaire(Exemple)(Exemple)

Page 59: Cours Structures de données

Représentation Contiguë Représentation Contiguë d'une Filed'une File

(par tableau circulaire) (1) (par tableau circulaire) (1)

00 11 22 33 44 55 66 77 88 99

tab

tete

queue

7

7

00 11 22 33 44 55 66 77 88 99

1100

2200

3300

4400

5500

tab

tete

queue

2

7

00 11 22 33 44 55 66 77 88 99

tab

tete

queue

0

0

00 11 22 33 44 55 66 77 88 99

55 22 1100

2200

3300

4400

5500

tab

tete

queue

0

7File initialement

vide qui peut contenir au plus

9 éléments(1)

(3) (4)

File après ajout de 5, 2, 10, 20,

30, 40 et 50(2)

File après suppression de 5

et 2

File après suppression de 10, 20, 30, 40 et

50

Page 60: Cours Structures de données

Représentation Contiguë Représentation Contiguë d'une Filed'une File

(par tableau circulaire) (2) (par tableau circulaire) (2)00 11 22 33 44 55 66 77 88 99

tab

tete

queue

7

7

(5)File vide

00 11 22 33 44 55 66 77 88 99

1100

55 1155

tab

tete

queue

7

0 File après ajout de

5, 15 et 10(6)

00 11 22 33 44 55 66 77 88 99

1100

55 66 2200

88 3355

2255

3333

1155

tab

tete

queue

8

7Après ajout de 5, 6, 20, 8, 35, 25,

et 33, File pleine!!

(8)

00 11 22 33 44 55 66 77 88 99

1100

1155

tab

tete

queue

8

0 File après suppression 5

(7)

Page 61: Cours Structures de données

/* fichier "TCfile.c" *//* fichier "TCfile.c" */

#include "Tfile.h"#include "Tfile.h"

// Définition des fonctions gérant la file // Définition des fonctions gérant la file // initialiser une nouvelle file// initialiser une nouvelle file File file_vide() {File file_vide() { File f; File f; f.queue = f.tete = 0;f.queue = f.tete = 0; return f;return f;}} // tester si la file est vide// tester si la file est videBooleen est_vide(File f) {Booleen est_vide(File f) { if (f.tete == f.queue) return vrai;if (f.tete == f.queue) return vrai; return faux;return faux;}}

// Valeur en tête de file// Valeur en tête de fileElement tete(File f) {Element tete(File f) {/* pré-condition : file non vide ! *//* pré-condition : file non vide ! */ if (est_vide(f)) { if (est_vide(f)) { printf("Erreur: file vide !\n"); printf("Erreur: file vide !\n"); exit(-1);exit(-1); }} return (f.tab)[(f.tete+1) % MAX_FILE];return (f.tab)[(f.tete+1) % MAX_FILE];}}

// ajout d'un élément// ajout d'un élémentFile enfiler(File f, Element e) {File enfiler(File f, Element e) { if (f.tete == (f.queue+1) % MAX_FILE) {if (f.tete == (f.queue+1) % MAX_FILE) { printf("Erreur : file pleine !\n"); printf("Erreur : file pleine !\n"); exit(-1);exit(-1); }} f.queue=(f.queue+1) % MAX_FILE;f.queue=(f.queue+1) % MAX_FILE; (f.tab)[f.queue] = e;(f.tab)[f.queue] = e; return f;return f;}}

// enlever un élément// enlever un élémentFile defiler(File f) {File defiler(File f) {/* pré-condition : file non vide !*//* pré-condition : file non vide !*/ if (est_vide(f)) {if (est_vide(f)) { printf("Erreur: file vide !\n"); printf("Erreur: file vide !\n"); exit(-1);exit(-1); }} f.tete=(f.tete+1) % f.tete=(f.tete+1) % MAX_FILEMAX_FILE;; return f;return f;}}

Réalisation d'une File Contiguë Réalisation d'une File Contiguë CirculaireCirculaire

Page 62: Cours Structures de données

File chaînéeFile chaînée

tete

File

10 20

50

30

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

// type des élémentstypedef int element;

// type Celluletypedef struct cellule { element valeur; struct cellule *suivant; } Cellule;

// type Filetypedef struct { struct cellule *tete; struct cellule *queue;} File;

Tête de la file pointée par

tete

Cellule contenant la

valeur 30

Pointeur sur cellule suivante

Pointeur NULLqueue

Queue de file pointée par

queue

Page 63: Cours Structures de données

Spécification d'une File Spécification d'une File ChaînéeChaînée/* fichier "Cfile.h" *//* fichier "Cfile.h" */

#ifndef _FILE_CHAINEE#ifndef _FILE_CHAINEE#define _FILE_CHAINEE#define _FILE_CHAINEE

#include "Booleen.h"#include "Booleen.h"

// Définition du type File (implémentée par pointeurs)// Définition du type File (implémentée par pointeurs)typedef int Element; typedef int Element; /* les éléments sont des /* les éléments sont des intint */ */

typedef struct cellule { typedef struct cellule { Element valeur; Element valeur; struct cellule *suivant;struct cellule *suivant;} Cellule;} Cellule;

typedef struct {typedef struct { struct cellule *tete;struct cellule *tete; struct cellule *queue;struct cellule *queue; } File;} File;

// Déclaration des fonctions gérant la file// Déclaration des fonctions gérant la fileFile pile_vide ();File pile_vide ();File enfiler ( File f, Element e ); File enfiler ( File f, Element e ); File defiler ( File f );File defiler ( File f );Element tete ( File f );Element tete ( File f );Booleen est_vide ( File f );Booleen est_vide ( File f );

#endif#endif

type File : structure type File : structure à deux champs à deux champs

(pointeurs de tête et (pointeurs de tête et de queue de file)de queue de file)

Une cellule Une cellule contient un contient un

élément et un élément et un pointeur sur pointeur sur

l'élément suivantl'élément suivant

Page 64: Cours Structures de données

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

/* fichier "Cfile.c" *//* fichier "Cfile.c" */

#include "alloc.h"#include "alloc.h"#include "Cfile.h"#include "Cfile.h"

File file_vide() { File file_vide() { File f;File f; f.tete=f.queue=NULL;f.tete=f.queue=NULL; return f;return f;}}

int est_vide(File f) { int est_vide(File f) { return (f.tete==NULL)&&(f.tete==NULL); return (f.tete==NULL)&&(f.tete==NULL); }}

Element tete(File f) {Element tete(File f) {/* pré-condition: file non vide ! *//* pré-condition: file non vide ! */ if (est_vide(f)) { if (est_vide(f)) { printf("Erreur: file vide !\n"); printf("Erreur: file vide !\n"); exit(-1);exit(-1); }} return (f.tete)->valeur;return (f.tete)->valeur;}}

File enfiler(File f, Element e) {File enfiler(File f, Element e) { Cellule * pc;Cellule * pc; pc=(Cellule *)malloc(sizeof(Cellule));pc=(Cellule *)malloc(sizeof(Cellule)); pc->valeur=e;pc->valeur=e; pc->suivant=NULL;pc->suivant=NULL; if (est_vide(f) if (est_vide(f) f.tete=f.queue=pc;f.tete=f.queue=pc; else f.queue=(f.queue)->suivant=pc;else f.queue=(f.queue)->suivant=pc; return f;return f;}}

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

Page 65: Cours Structures de données

ComplexitéComplexité

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

Ceci est valable pour les deux Ceci est valable pour les deux représentations : file contiguë représentations : file contiguë circulaire et file chaînéecirculaire et file chaînée

Page 66: Cours Structures de données

Applications d'une FileApplications d'une FileExemplesExemples

Gestion des travaux d’impression d’une Gestion des travaux d’impression d’une

imprimante :imprimante : Cas d'une imprimante en réseau, où les tâches d'impressions Cas d'une imprimante en réseau, où les tâches d'impressions

arrivent aléatoirement de n'importe quel ordinateur connecté. arrivent aléatoirement de n'importe quel ordinateur connecté. Les tâches sont placées dans une file d'attente, ce qui permet Les tâches sont placées dans une file d'attente, ce qui permet de les traiter selon leur ordre d'arrivéede les traiter selon leur ordre d'arrivée

Ordonnanceur (Ordonnanceur (dans les systèmes d’exploitationdans les systèmes d’exploitation) :) : Maintenir une file de processus en attente d’un temps

machine ; ;

Parcours « en largeur » d’un arbreParcours « en largeur » d’un arbre ((voir arbresvoir arbres))

Page 67: Cours Structures de données

Les Listes (Lists)Les Listes (Lists)

Page 68: Cours Structures de données

Notion de Liste (List) (1)Notion de Liste (List) (1) Généralisation des piles et des filesGénéralisation des piles et des files

Structure linéaire dans laquelle les éléments peuvent être traités Structure linéaire dans laquelle les éléments peuvent être traités les uns à la suite des autres les uns à la suite des autres

Ajout ou retrait d'éléments n’importe où dans la liste Ajout ou retrait d'éléments n’importe où dans la liste Accès à n'importe quel élémentAccès à n'importe quel élément

Une liste est une suite finie, Une liste est une suite finie, éventuellement vide,éventuellement vide, d'éléments de d'éléments de même typemême type repérés par leur repérés par leur rangrang dans la listedans la liste

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

Exemple :Exemple : une liste de 5 entiers L = <4, 1, 7, 3, 1> (une liste de 5 entiers L = <4, 1, 7, 3, 1> (place de rang 1 place de rang 1

contient la valeur 4contient la valeur 4)) une liste vide L2 = <>une liste vide L2 = <>

Page 69: Cours Structures de données

Notion de Liste (List) (2)Notion de Liste (List) (2) Les éléments d'une liste sont donc

ordonnés en fonction de leur place

Il existe Il existe une fonctionune fonction notée notée succsucc qui, qui, appliquée à toute place sauf la dernière, appliquée à toute place sauf la dernière, fournit la place suivantefournit la place suivante

Le nombre total d'élémentsLe nombre total d'éléments, et par , et par conséquent de places, est appelé conséquent de places, est appelé longueur longueur de la listede la liste

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

Page 70: Cours Structures de données

Exemples de ListeExemples 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

Page 71: Cours Structures de données

Type Abstrait Liste (1)Type Abstrait Liste (1)

TypeType ListeListeUtiliseUtilise Elément, Booléen, Place Elément, Booléen, PlaceOpérationsOpérations

liste_videliste_vide : : Liste Listelongueur longueur  : Liste : Liste Entier Entierinsérer insérer  : Liste x Entier x Elément : Liste x Entier x Elément Liste Listesupprimersupprimer : Liste x Entier : Liste x Entier Liste Listekèmekème : Liste x Entier : Liste x Entier Elément Elémentaccès accès  : Liste x Entier : Liste x Entier Place Placecontenucontenu : Liste x Place : Liste x Place Elément Elémentsuccsucc : Liste x Place : Liste x Place Place Place

PréconditionsPréconditionsinsérer(l,k,e) insérer(l,k,e) est-défini-ssi est-défini-ssi 1 ≤ k ≤ longueur(l)+11 ≤ k ≤ longueur(l)+1supprimer(l,k) supprimer(l,k) est-défini-ssi est-défini-ssi 1 ≤ k ≤ longueur(l)1 ≤ k ≤ longueur(l)kème(l,k) kème(l,k) est-défini-ssi est-défini-ssi 1 ≤ k ≤ longueur(l)1 ≤ k ≤ longueur(l)accès(l,k) accès(l,k) est-défini-ssiest-défini-ssi 1 ≤ k ≤ longueur(l) 1 ≤ k ≤ longueur(l)succ(l,p) succ(l,p) est-défini-ssi est-défini-ssi p ≠ accès(l,longueur(l)) p ≠ accès(l,longueur(l))

k = longueur(l) + 1 signifie ajout en fin

de liste

Page 72: Cours Structures de données

Type Abstrait Liste (2)Type Abstrait Liste (2)AxiomesAxiomes

Soit, e : Elément, l, l' : Liste, k, j : EntierSoit, e : Elément, l, l' : Liste, k, j : Entier

si l = liste_vide alors longueur(l) = 0si l = liste_vide alors longueur(l) = 0sinon si l = insérer(l',k,e) alors longueur(l)=longueur(l')+1sinon si l = insérer(l',k,e) alors longueur(l)=longueur(l')+1 sinon soit l = supprimer(l',k)alors longueur(l)=longueur(l')-1sinon 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)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) = esinon 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)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)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)sinon kème(supprimer(l,k),j) = kème(l,j+1)

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

si 1 ≤ k < j longueur(l) alors si 1 ≤ k < j longueur(l) alors contenu(l,accès(supprimer(l,j),k)) = contenu(l,accès(l,k))contenu(l,accès(supprimer(l,j),k)) = contenu(l,accès(l,k))si 1 ≤ k ≤ j < longueur(l) alors si 1 ≤ k ≤ j < longueur(l) alors contenu(l,accès(supprimer(l,j),k) = contenu(l,accès(l,k+1))contenu(l,accès(supprimer(l,j),k) = contenu(l,accès(l,k+1))si 1 ≤ j < k 1+longueur(l) alors si 1 ≤ j < k 1+longueur(l) alors contenu(l,accès(insérer(l,k,e),j) = contenu(l,accès(l,j))contenu(l,accès(insérer(l,k,e),j) = contenu(l,accès(l,j))si 1 ≤ k = j 1+longueur(l) alors si 1 ≤ k = j 1+longueur(l) alors contenu(l,accès(insérer(l,k,e),j) = econtenu(l,accès(insérer(l,k,e),j) = esi 1 ≤ k < j 1+longueur(l) alors 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))contenu(l,accès(insérer(l,k,e),j) = contenu(l,accès(l,j-1))

Page 73: Cours Structures de données

Extension Type Abstrait Extension Type Abstrait ListeListe

Extension type Extension type ListeListeOpérationsOpérations

concaténer : liste x liste concaténer : liste x liste Liste Listerechercher : Liste x Elément rechercher : Liste x Elément Place Place

PréconditionsPréconditionsrechercher(l,e) rechercher(l,e) est-défini-ssiest-défini-ssi longueur(l) ≠ 0 longueur(l) ≠ 0

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

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

sisi k ≤ longueur(l) k ≤ longueur(l) alorsalors kème(concaténer(l,l'),k)= kème(l,k) kème(concaténer(l,l'),k)= kème(l,k)sinonsinon kème(concaténer(l,l'),k)= kème(l',k-longueur(l)) kème(concaténer(l,l'),k)= kème(l',k-longueur(l))

sisi kème(l,1)=e kème(l,1)=e ouou longueur(supprimer(l,1)) = 0 longueur(supprimer(l,1)) = 0 alors alors rechercher(l,e) = accès(l,1)rechercher(l,e) = accès(l,1)sinon sinon rechercher(l,e) = rechercher(supprimer(l,1))rechercher(l,e) = rechercher(supprimer(l,1))

Page 74: Cours Structures de données

Opérations sur une Liste Opérations sur une Liste (1)(1)

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

longueur : Liste longueur : Liste Entier Entier Retourne le nombre d'éléments dans la listeRetourne le nombre d'éléments dans la liste

insérer : Liste x Entier x Elément : insérer : Liste x Entier x Elément : Liste Liste insérer(L,j,e)insérer(L,j,e):: liste obtenue à partir de liste obtenue à partir de LL en remplaçant en remplaçant

la place la place jj par une place contenant par une place contenant ee, sans modifier places , sans modifier places précédentes et en décalant places suivantesprécédentes et en décalant places suivantes

supprimer : Liste x Entier : supprimer : Liste x Entier : Liste Liste supprimer(L,j)supprimer(L,j):: liste obtenue à partir de liste obtenue à partir de LL en supprimant en supprimant

la place la place jj et son contenu, sans modifier places précédentes et son contenu, sans modifier places précédentes et en décalant places suivanteset en décalant places suivantes

Page 75: Cours Structures de données

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

accès : Liste x Entier accès : Liste x Entier Place Place Connaître la place de rang donné : Connaître la place de rang donné : accès(L,k)accès(L,k) est la place est la place

de rang de rang k k dans la liste dans la liste LL

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

succ : Liste x Place succ : Liste x Place Place Place Passer de place en place. Passer de place en place. succ(L,p) = p'succ(L,p) = p' : dans la liste : dans la liste LL, ,

la place qui succède à la place la place qui succède à la place pp est la place est la place p'p'. Opération . Opération indéfinie si place en entrée est la dernière place de la listeindéfinie si place en entrée est la dernière place de la liste

Opérations sur une Liste Opérations sur une Liste (2)(2)

Page 76: Cours Structures de données

concaténer : liste x liste concaténer : liste x liste Liste Liste Accroche deuxième liste en entrée à la fin de la Accroche deuxième liste en entrée à la fin de la

première listepremière liste

rechercher : Liste x Elément rechercher : Liste x Elément Place Place Recherche la place occupée par un élément dans Recherche la place occupée par un élément dans

une liste (une liste (Ceci suppose que l'élément figure dans Ceci suppose que l'élément figure dans la listela liste))

est_présent : Liste x Elément est_présent : Liste x Elément Booléen Booléen Teste si un élément figure dans une listeTeste si un élément figure dans une liste

Opérations Auxiliaires sur Opérations Auxiliaires sur une Listeune Liste

Page 77: Cours Structures de données

Représentation Contiguë Représentation Contiguë d'une Listed'une Liste

Les éléments sont rangés les uns à côté des autres Les éléments sont rangés les uns à côté des autres dans un tableaudans un tableau La ième case du tableau contient le ième élément de la La ième case du tableau contient le ième élément de la

listeliste Le rang est donc égal à la place ; ce sont des entiersLe rang est donc égal à la place ; ce sont des entiers

La liste est représentée par une structure en La liste est représentée par une structure en langage C :langage C : Un tableau représente les élémentsUn tableau représente les éléments Un entier représente le nombre d'éléments dans la listeUn entier représente le nombre d'éléments dans la liste La longueur maximale, La longueur maximale, MAX_LISTEMAX_LISTE, de la liste doit être , de la liste doit être

connueconnue

Page 78: Cours Structures de données

Ajout dans une Liste Ajout dans une Liste ContiguëContiguë

5

Valeur à ajouter au

deuxième rang

Liste après insertion de la valeur 5

Faire de la place par Décalage vers

la droite

10tab

0 1 2 3 4 5 6 7

15207

5

Page 79: Cours Structures de données

Suppression dans une Liste Suppression dans une Liste ContiguëContiguë

Valeur 10 à supprimer

(premier rang)

Liste après suppression de la valeur 10

Faire un décalage vers la gauche

d'un rang

10tab

0 1 2 3 4 5 6 7

2075

10

15

Page 80: Cours Structures de données

Liste Contiguë Liste Contiguë (Contiguous List)(Contiguous List)

/* Liste contiguë en C */

// taille maximale liste#define MAX_LISTE 10

// type des élémentstypedef int Element;

// type Placetypedef int Place;

// type Listetypedef struct { Element tab[MAX_LISTE]; int taille; } Liste;

00 11 22 33 44 55 66 77 88 99

1100

66 3300

4400

5500

tab

taille 5

Liste

Tableau de taille

maximale = 10

Nombre d'éléments dans la liste

La place du rang 3 contient

la valeur 40

Page 81: Cours Structures de données

Spécification d'une Liste Spécification d'une Liste ContiguëContiguë/* fichier "TListe.h" *//* fichier "TListe.h" */

#ifndef _LISTE_TABLEAU#ifndef _LISTE_TABLEAU#define _LISTE_TABLEAU#define _LISTE_TABLEAU

// Définition du type liste (implémentée par tableau)// Définition du type liste (implémentée par tableau)#define MAX_LISTE 100 #define MAX_LISTE 100 /* taille maximale de la liste *//* taille maximale de la liste */typedef int element; typedef int element; /* les éléments sont des int *//* les éléments sont des int */

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

typedef struct {typedef struct { element tab[MAX_LISTE]; element tab[MAX_LISTE]; // les éléments de la liste// les éléments de la liste int taille; int taille; // nombre d'éléments dans la liste// nombre d'éléments dans la liste} Liste;} Liste;

// Déclaration des fonctions gérant la liste// Déclaration des fonctions gérant la listeListe liste_vide (void);Liste liste_vide (void);int longueur (Liste l);int longueur (Liste l);Liste inserer (Liste l, int i, element e);Liste inserer (Liste l, int i, element e);Liste supprimer (Liste l, int i);Liste supprimer (Liste l, int i);element keme (Liste l, int k);element keme (Liste l, int k);

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

#endif#endif

type Liste : une structure à deux

champs

Page 82: Cours Structures de données

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

Liste liste_vide(void) {Liste liste_vide(void) { Liste l;Liste l; l.taille = 0;l.taille = 0; return l;return l;}}

int longueur(Liste l) {int longueur(Liste l) { return l.taille;return l.taille;}}

Liste inserer(Liste l, int i, element e) {Liste inserer(Liste l, int i, element e) {// précondition :// précondition : longueur(l) = MAX_LISTElongueur(l) = MAX_LISTE// et// et 0 ≤ i < longueur(l)+10 ≤ i < longueur(l)+1 int r;int r; if (longueur(l) == MAX_LISTE) { if (longueur(l) == MAX_LISTE) { printf("Erreur : liste saturée !\n"); printf("Erreur : liste saturée !\n"); exit(-1); exit(-1); } } if (i<0 || i>longueur(l)) {if (i<0 || i>longueur(l)) { printf("Erreur : rang non valide !\n"); printf("Erreur : rang non valide !\n"); exit(-1); exit(-1); } } for (r = longueur(l); r>i; r--)for (r = longueur(l); r>i; r--) l.tab[r] = l.tab[r-1]; l.tab[r] = l.tab[r-1]; l.tab[i] = e; l.tab[i] = e; (l.taille)++; (l.taille)++; return l;return l;}}

Liste supprimer(Liste l, int i) {Liste supprimer(Liste l, int i) {// précondition :// précondition : 0 ≤ i < longueur(l)0 ≤ i < longueur(l) int r;int r; if (i<0 || i>longueur(l)-1) if (i<0 || i>longueur(l)-1)

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

exit(-1);exit(-1); } } for (r = i; r<for (r = i; r<longueur(l)-1;longueur(l)-1;; r++) ; r++)

l.tab[r] = l.tab[r+1];l.tab[r] = l.tab[r+1]; (l.taille)--; (l.taille)--; return l;return l;}}

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

Page 83: Cours Structures de données

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

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

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

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

Page 84: Cours Structures de données

Les éléments ne sont pas rangés les uns à côté Les éléments ne sont pas rangés les uns à côté des autresdes autres La place d'un élément est l'adresse d'une structure qui 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 contient l'élément ainsi que la place de l'élément suivant suivant

Utilisation de pointeurs pour chaîner entre eux les Utilisation de pointeurs pour chaîner entre eux les éléments successifs éléments successifs

La liste est représentée par un pointeur sur une La liste est représentée par un pointeur sur une structure en langage C structure en langage C Une structure contient un élément de la liste et un Une structure contient un élément de la liste et un

pointeur sur l'élément suivantpointeur sur l'élément suivant La liste est déterminée par un pointeur sur son premier La liste est déterminée par un pointeur sur son premier

élémentélément La liste vide est représentée par la constante prédéfinie La liste vide est représentée par la constante prédéfinie

NULLNULL

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

Page 85: Cours Structures de données

Ajout dans une Liste Ajout dans une Liste ChaînéeChaînée

5

10 2010 205

Valeur à ajouter entre

les deux cellules

LL

Liste après insertion de la valeur 5

Création d'une nouvelle cellule

Page 86: Cours Structures de données

Suppression dans une Liste Suppression dans une Liste ChaînéeChaînée

Supprimer valeur 5

10 205

L

10 20

L

Liste après suppression de la valeur 5

Libérer espace occupé par la

cellule

Page 87: Cours Structures de données

Liste Chaînée (Linked Liste Chaînée (Linked List)List)

L

Liste

10 6

50

30

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

// type des élémentstypedef int element;

// type Placetypedef struct cellule* Place;

// type Celluletypedef struct cellule { element valeur; struct cellule *suivant; } Cellule;

// type Listetypedef Cellule *Liste;

Premier élément de la liste pointée

par L

Cellule contenant la

valeur 30

Pointeur sur cellule suivante

Pointeur NULL

Dernier élément de la

liste

Page 88: Cours Structures de données

Spécification d'une Liste Spécification d'une Liste ChaînéeChaînée/* fichier "CListe.h" *//* fichier "CListe.h" */

#ifndef _LISTE_CHAINEE#ifndef _LISTE_CHAINEE#define _LISTE_CHAINEE#define _LISTE_CHAINEE

// Définition du type liste (implémentée par pointeurs)// Définition du type liste (implémentée par pointeurs)typedef int element; /* les éléments sont des int */typedef int element; /* les éléments sont des int */

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

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

typedef Cellule *Liste;typedef Cellule *Liste;

// Déclaration des fonctions gérant la liste// Déclaration des fonctions gérant la listeListe liste_vide (void);Liste liste_vide (void);int longueur (Liste l);int longueur (Liste l);Liste inserer (Liste l, int i, element e);Liste inserer (Liste l, int i, element e);Liste supprimer (Liste l, int i);Liste supprimer (Liste l, int i);element keme (Liste l, int k);element keme (Liste l, int k);

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

#endif#endif

type Liste : un pointeur de Cellule

Page 89: Cours Structures de données

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

Liste liste_vide(void) {Liste liste_vide(void) { return NULL;return NULL;}}

int longueur(Liste l) {int longueur(Liste l) { int taille=0;int taille=0; Liste p=l;Liste p=l; while (p) {while (p) { taille++;taille++; p=p->suivant;p=p->suivant; }} return taille;return taille;}}

Liste inserer(Liste l, int i, element e) {Liste inserer(Liste l, int i, element e) {// précondition :0 ≤ i < longueur(l)+1// précondition :0 ≤ i < longueur(l)+1 if (i<0 || i>longueur(l)) {if (i<0 || i>longueur(l)) { printf("Erreur : rang non valide !\n"); printf("Erreur : rang non valide !\n"); exit(-1); exit(-1); } } Liste pc = (Liste)malloc(sizeof(Cellule));Liste pc = (Liste)malloc(sizeof(Cellule)); pc->valeur=e;pc->valeur=e; pc->suivant=NULL;pc->suivant=NULL; if (i==0){if (i==0){ pc->suivant=l; pc->suivant=l; l=pc;l=pc; }}

else {else { int j;int j; Liste p=l;Liste p=l; for (j=0; j<i-1; j++)for (j=0; j<i-1; j++) p=p->suivant;p=p->suivant; pc->suivant=p->suivant;pc->suivant=p->suivant; p->suivant=p;p->suivant=p; }} return l;return l;}}

Place acces(Liste l, int k) {Place acces(Liste l, int k) {// pas de sens que si 0 ≤ k ≤ longueur(l)-1// pas de sens que si 0 ≤ k ≤ longueur(l)-1

int i;int i; Place p;Place p; if (k<0 || k>=longueur(l)) {if (k<0 || k>=longueur(l)) { printf("Erreur: rang invalide !\n");printf("Erreur: rang invalide !\n"); exit(-1);exit(-1); }} if (k == 0)if (k == 0) return l;return l; else {else { p=l;p=l; for(i=0; i<k; k++)for(i=0; i<k; k++) p=p->suivant;p=p->suivant; return p;return p; }}}}

Page 90: Cours Structures de données

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

element contenu(Liste l, Place p) {element contenu(Liste l, Place p) {// pas de sens si longueur(l)=0 (liste vide)// pas de sens si longueur(l)=0 (liste vide) if (longueur(l) == 0) { if (longueur(l) == 0) { printf("Erreur: liste vide !\n"); printf("Erreur: liste vide !\n"); exit(-1); exit(-1); }} return p->valeur;return p->valeur;}}

Place succ(Liste l, Place p) {Place succ(Liste l, Place p) {// pas de sens si p dernière place de liste// pas de sens si p dernière place de liste if (p->suivant == NULL) { if (p->suivant == NULL) { printf("Erreur: suivant dernière place!\n"); printf("Erreur: suivant dernière place!\n"); exit(-1); exit(-1); } } return p->suivant;return p->suivant;}}

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

Liste supprimer(Liste l, int i) {Liste supprimer(Liste l, int i) {// précondition : 0 ≤ i < longueur(l)// précondition : 0 ≤ i < longueur(l) int j;int j; Liste p;Liste p; if (i<0 || i>longueur(l)+1) {if (i<0 || i>longueur(l)+1) { printf("Erreur: rang non valide!\n");printf("Erreur: rang non valide!\n"); exit(-1);exit(-1); }} if (i == 0) {if (i == 0) { p=l;p=l; l=l->suivant;l=l->suivant; }} else {else { Place q;Place q; q=acces(l,i-1);q=acces(l,i-1); p=succ(l,q);p=succ(l,q); q->suivant=p->suivant;q->suivant=p->suivant; }} free(p);free(p); return l;return l;}}

Page 91: Cours Structures de données

Remarques (1)Remarques (1) Ajout au milieu d'une liste connaissant la Ajout au milieu d'une liste connaissant la

place qui précède celle où s'effectuera l'ajoutplace qui précède celle où s'effectuera l'ajout ajouter : Liste x Place x Elément ajouter : Liste x Place x Elément Liste Liste ajouter(L,p,e)ajouter(L,p,e) : : liste obtenue à partir de liste obtenue à partir de LL en en

ajoutant une place contenant l'élément ajoutant une place contenant l'élément ee, juste , juste après la place après la place pp

Enlever un élément d'une liste connaissant Enlever un élément d'une liste connaissant sa placesa place enlever : Liste x Place enlever : Liste x Place Liste Liste enlever(L,p)enlever(L,p) : : liste obtenue à partir de liste obtenue à partir de LL en en

supprimant la place supprimant la place pp et son contenu et son contenu

Page 92: Cours Structures de données

Remarques (2)Remarques (2)

Liste ajouter(Liste l, Liste ajouter(Liste l, Place p, element e) {Place p, element e) { Liste pc;Liste pc; pc=(Liste)malloc(sizeof(Cellule));pc=(Liste)malloc(sizeof(Cellule)); if (pc == NULL) {if (pc == NULL) { printf("Erreur: Problème de " printf("Erreur: Problème de " "mémoire\n"); "mémoire\n"); exit(-1);exit(-1); }} pc->valeur = e;pc->valeur = e; pc->suivant = p->suivant;pc->suivant = p->suivant; p->suivant = pcp->suivant = pc return l;return l;}}

Liste enlever(Liste l, Place p) {Liste enlever(Liste l, Place p) {// p pointe élément à supprimer// p pointe élément à supprimer Place pred; Place pred; //pred pointe avant p//pred pointe avant p if (p == l) if (p == l) l = succ(l,p);l = succ(l,p); else { else { pred=l; pred=l; while (succ(l,pred) != p) while (succ(l,pred) != p) pred = succ(l,pred); pred = succ(l,pred); pred->suivant = p->suivant; pred->suivant = p->suivant; } } free(p);free(p); return l;return l;}}

Page 93: Cours Structures de données

Variantes de Listes Variantes de Listes ChaînéesChaînées

Liste avec tête fictive Liste avec tête fictive

Liste chaînée circulaireListe chaînée circulaire

Liste doublement chaînéeListe doublement chaînée

Liste doublement chaînéeListe doublement chaînée circulairecirculaire

Liste triéeListe triée

Page 94: Cours Structures de données

Liste avec Tête FictiveListe avec Tête Fictive

Eviter d'avoir un traitement particulier Eviter d'avoir un traitement particulier pour le cas de la tête de liste (pour le cas de la tête de liste (opérations opérations d'insertion et de suppressiond'insertion et de suppression)) Mettre en tête de liste une zone qui ne contient Mettre en tête de liste une zone qui ne contient

pas de valeur et reste toujours en têtepas de valeur et reste toujours en tête

Page 95: Cours Structures de données

Liste CirculaireListe Circulaire

Le suivant du dernier élément de la liste est le pointeur de tête

Page 96: Cours Structures de données

Liste Doublement Liste Doublement ChaînéeChaî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

Page 97: Cours Structures de données

Liste TriéeListe Triée

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

L’ordre des enregistrements dans L’ordre des enregistrements dans la liste respecte l’ordre sur les clésla liste respecte l’ordre sur les clés

10 2015

L

Page 98: Cours Structures de données

ComplexitéComplexité n désigne le n désigne le nombre d'éléments nombre d'éléments d'une d'une

listeliste

Page 99: Cours Structures de données

Représentation par Curseurs Représentation par Curseurs d'une Listed'une Liste

Curseurs (ou faux pointeurs) utilisés dans Curseurs (ou faux pointeurs) utilisés dans le cas d'un langage ne supportant pas les le cas d'un langage ne supportant pas les pointeurs (pointeurs (par exemple, Fortranpar exemple, Fortran))

La liste est représentée par une structure à La liste est représentée par une structure à trois champs en langage C :trois champs en langage C : Un tableau de couples (élément, suivant)Un tableau de couples (élément, suivant) Un entier (Un entier (tetetete) désignant début de liste des éléments) désignant début de liste des éléments Un entier (Un entier (dispodispo) désignant début de liste des cases ) désignant début de liste des cases

libreslibres Liste vide : Liste vide : tete tete -1 -1 et et dispo dispo 0 0

Page 100: Cours Structures de données

Liste Chaînée par Liste Chaînée par CurseursCurseurs

3tete

Liste

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

// taille maximale liste#define MAX_LISTE 7

// type des élémentstypedef int element;

// type Celluletypedef struct cellule { element valeur; int suivant; } Cellule;

// type Listetypedef struct { Cellule cellules[MAX_LISTE]; int tete; int dispo;} Liste;

1010 -1-1

2020 55

5050 11

3030 00

valeur

suivant0

1

4

3

2

6

52dispo

Début de liste des places occupées

Début de liste des

places libres

Tableau de taille

maximale = 7

Page 101: Cours Structures de données

Exemples d'Applications Exemples d'Applications d'une Listed'une Liste

Codage des polynômesCodage des polynômes : : la liste d'entiers (la liste d'entiers (0,1,0,-2,40,1,0,-2,4) représente le polynôme à ) représente le polynôme à

une indéterminée une indéterminée XX : : 4 X4 X44 - X - X33 + X + X

Codage des grands nombresCodage des grands nombres

Codage des matrices creuses Codage des matrices creuses

Implémentation d’un logiciel de traitement de Implémentation d’un logiciel de traitement de texte :texte : Un texte est représenté par une liste de paragraphesUn texte est représenté par une liste de paragraphes

Représentation d’un grapheReprésentation d’un graphe


Recommended