Cours Structures de données
description
Transcript of 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
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
Types Abstraits Types Abstraits de Données de Données
(TADs)(TADs)Spécification & Spécification & ImplémentationImplémentation
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))
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.
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
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
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
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
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)
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
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
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
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 ?
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
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
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.
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)
Structures de Structures de Données Données LinéairesLinéaires
Piles, Files & listesPiles, Files & listes
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.
Les Piles (Stacks)Les Piles (Stacks)
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.
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
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)
A
B
C
D
E
F
Pile
Exemple de Pile (2)Exemple de Pile (2)
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
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
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
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
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
/* 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ë
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;}}
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
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
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
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;}}
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
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 ;
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) ;) ;
Les Files Les Files (Queues)(Queues)
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
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
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
A EB D FC
Exemple de File (2)Exemple de File (2)
File
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)
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
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
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 !
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
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)
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
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
/* 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ë
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
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
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)
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
File Contiguë CirculaireFile Contiguë Circulaire(Exemple)(Exemple)
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
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)
/* 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
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
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
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;}}
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
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))
Les Listes (Lists)Les Listes (Lists)
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 = <>
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
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
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
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))
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))
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
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)
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
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
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
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
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
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
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];}}
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)
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
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
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
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
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
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; }}}}
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;}}
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
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;}}
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
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
Liste CirculaireListe Circulaire
Le suivant du dernier élément de la liste est le pointeur de tête
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
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
ComplexitéComplexité n désigne le n désigne le nombre d'éléments nombre d'éléments d'une d'une
listeliste
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
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
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