Vous êtes sur la page 1sur 33

STRUCTURES DE DONNEES

Chapitre 2
Liste Chainée

Pr: Mohamed EL FAR


Liste Chainée
2

Objectifs recherchés :

 Allouer de l’espace mémoire en fonction du besoin.


 Simuler des phénomènes du monde réel :
 File d’attente dans un guichet.
 Urgences dans un hôpital.
 Dossiers empilés sur un bureau.

PR M.EL FAR 26/02/2022


Liste Chainée
3

Une liste chainée est un ensemble d’éléments qui


constituent ses nœuds,
Au contraire des tableaux, les éléments d’une liste
chainée ne sont pas placés côte à côte.

PR M.EL FAR 26/02/2022


Liste Chainée
4

Exemple de problème à résoudre

PR M.EL FAR 26/02/2022


Liste Chainée
5

Résolution du problème

Principe de base
chaque élément peut avertir son suivant
Tableaux ? Liste chainée ?
Nombre d’éléments inconnu Méthode adoptée pour les tailles dynamiques
méthode à écarter
PR M.EL FAR 26/02/2022
Liste Chainée
6

Définition :
Une structure de données composée d’éléments de même
type reliés de façon successive par des pointeurs..

PR M.EL FAR 26/02/2022


Liste Chainée
7

Composition :

Dans une liste chaînée les éléments sont rangés linéairement. Chaque élément est lié à son
successeur, il est donc impossible d'accéder directement à un élément quelconque de la liste.
Cette linéarité est virtuelle.
PR M.EL FAR 26/02/2022
Liste Chainée
8

Représentation en C

PR M.EL FAR 26/02/2022


Liste Chainée
9

li -> premier li -> dernier li -> nbElt

li 3
liste Liste chaînée
a b c

cellule
 une cellule est composée :
 d’un élément de la suite

 d’un lien vers la cellule suivante (pointeur)

 une liste chaînée est composé d’un ensemble de cellule


liste contient l’adresse de la première cellule; qui à son tour contient l’adresse de
la cellule suivante, ...
Liste Chainée
• Pour que le module de gestion des listes soit le plus général possible, il faut bien
séparer ce qui est spécifique des listes de ce qui est caractéristique des applications.

typedef void Objet; // Le type liste


// Un élément de la liste typedef struct {
typedef struct element { Element *premier;
Objet *data; Element *dernier;
struct element* suivant; int nbElt;
} Element; } Liste;
Les principales opérations sur une liste chainée
L’interface List.h

#ifndef LISTE_H //les opérations sur la liste


#define LISTE_H
// definition de type boolean avec vrai et faux void initListe(Liste *li);
#define faux 0 Liste* creerListe();
#define vrai 1
typedef int boolean; boolean listeVide(Liste *li);
typedef void Objet; void insererEnTeteDeListe(Liste *li,Objet *o);
// un élément de la liste
typedef struct element { void insererEnFinDeListe(Liste *li,Objet *o);
Objet*data; Objet* extraireEnTeteDeListe (Liste* li);
struct element *suivant;
} Element; Objet* extraireApres(Liste* li,Element* precedent);
// le type Liste Objet* extraireEnFinDeListe (Liste* li);
typedef struct {
Element *premier; // parcours de la liste
Element *dernier;//optionnel void listerListe(Liste *li,void (*f) (Objet*));
int nbElt;
} Liste; Objet *chercherUnObjet(Liste *li,Objet *o,
boolean (*f) (Objet *, Objet *));
Les principales opérations sur une
liste chainée
Initialisation et création d’une liste
// Initialisation de la liste // Création de la liste
void initListe(Liste *li) Liste* creerListe()
{ {
li->premier =NULL; Liste* li;
li->dernier =NULL; li=(Liste*)malooc(sizeof(Liste));
li->nbElt=0; initListe (li);
} return li;
}

•Premier pointe sur le premier élément de la liste


•Dernier pointe sur le dernier élément de la list
Ajout en tête

li -> premier li -> dernier li -> nbElt

li 3

List *li;
Ajout en tête
li 3
4

data Data data null


1 2 3

li -> premier = nouveau;


objet nouveau -> suivant = li -> premier;
li -> nbElt ++;
Nouveau

// Création du nouveau element nouveau -> suivant = li -> premier;


void insererEnTeteDeListe (Liste* li, Objet* objet) li -> premier = nouveau;
{Element* nouveau; if (li->dernier == NULL)
nouveau=(Element*)malloc(sizeof(Element)); li -> dernier = nouveau;
nouveau->data=objet; li -> nbElt ++;
Ajout après un précédent
li 4
3 précédent Précédent -> suivant

data Data data null


1 2 3

precedent -> suivant = nouveau;


objet nouveau -> suivant= precedent -> suivant;
li -> nbElt ++;
Nouveau
void insererApres (Liste* li, Element*
nouveau -> suivant= precedent -> suivant;
precedent, Objet* objet)) {
precedent -> suivant = nouveau;
if (precedent == NULL) {
if (precedent == li->dernier)
insererEnTeteDeListe (li, objet);}
li->dernier = nouveau;
else {
li->nbElt++;
Element* nouveau = CreerElement();
} }
nouveau->data=objet;
Ajout en fin de liste
li 3
4

data Data data null


1 2 3

li-> dernier -> suivant = nouveau; objet

Nouveau
Void insererFinListe(Liste*li,Objet* objet) { Else {
Element* nouveau = CreerElement(); li-> dernier -> suivant = nouveau;
nouveau->data=objet; li->dernier = nouveau;
if (li->premier == NULL) li->nbElt++;
insereren TeteListe(Liste*li,Objet* objet); }
Supprimer un élément en tête de liste

li 3
2

data Data data null


1 2 3

Extrait
Element* extrait = li -> premier;
Objet* extraireEnTeteDeListe (Liste* li) {
Element* extrait = li->premier; li -> premier = li -> premier ->
if (!listeVide(li)) { suivant;
li -> premier = li -> premier -> suivant;
if (li->premier==NULL) // Liste devenue vide
li -> dernier=NULL;
li->nbElt--;}
return extrait != NULL ? extrait->reference : NULL;
}
Supprimer un élément en tête de liste
Supprimer un élément en tête de liste
li 3
2

data Data data null


1 2 3

Liste* SupprimerTeteDeListe (Liste* li) {


Extrait
Element* e = li->premier;
if (listeVide(li)) { return li;}
if (!listeVide(li)) {
free(e);
li -> premier = li -> premier -> suivant;
if (li->premier==NULL) // Liste devenue vide
li -> dernier=NULL;
li->nbElt--;}
Return li; }
Supprimer un élément en Fin de liste
Supprimer un élément en Fin de liste
li 3
2

data Data data null


1 2 3

Liste* extraireFinDeListe (Liste* li) { NULL Extrait


Element *e= li->premier;
if (listeVide(li)) { return li;}
If(li->nbElt==1) {
free(li); li->nbElt--;
return NULL;}
while(e ->suiv ->suiv!=NULL) e=e ->suiv;
free(e ->suiv);
li ->derneir=e;
e ->suiv=NULL;
li->nbElt--;
return li;}
Les listes doublement chainées
Les listes doublement chainées
Les listes doublement chainées
25

li -> premier li -> dernier li -> nbElt

li 3
liste
Liste Doublement
a b c Chaînée

cellule
typedef void Objet; // le type Liste
// un élément de la liste typedef struct {
typedef struct element { Element *premier;
Objet*data; Element *dernier;//optionnel
struct element *suivant; int nbElt;
struct element *precedent; } Liste;
} Element;
Initialisation et création d’une liste
Doublement Chainée
// Initialisation de la liste // Création de la liste
void initListe(Liste *li) Liste* creerListe()
{ {
li->premier =NULL; Liste* li;
li->dernier =NULL; li=(Liste*)malooc(sizeof(Liste));
li->nbElt=0; initListe (li);
} return li;
}

•Premier pointe sur le premier élément de la liste


•Dernier pointe sur le dernier élément de la list
Les listes doublement chainées
Insertion au début
Les listes doublement chainées
Insertion au début

li -> premier = nouveau;


// Création du nouveau element
li -> dernier = nouveau; }
void insererEnTeteDeListe (Liste* li, Objet* objet) {
Else{
Element* nouveau;
li -> premier ->prec=nouveau;
nouveau=(Element*)malloc(sizeof(Element));
nouveau -> suivant= li -> premier ;
nouveau -> suiv=NULL;
li -> premier=nouveau;
nouveau -> prec=NULL
}
nouveau->data=objet;
li -> nbElt ++;
if (li->dernier == NULL) {
}
nouveau -> suivant =NULL;
Les listes doublement chainées
Insertion à la fin
Les listes doublement chainées
Insertion à la fin

// Création du nouveau element li -> premier = nouveau;


void insererEnFinDeListe (Liste* li, Objet* objet) { li -> dernier = nouveau; }
Element* nouveau; Else{
nouveau=(Element*)malloc(sizeof(Element)); li -> dernier ->suiv=nouveau;
nouveau -> suiv=NULL; nouveau -> prec= li -> dernier ;
nouveau -> prec=NULL li -> dernier=nouveau;
nouveau->data=objet; }
if (li->dernier == NULL) { li -> nbElt ++;
nouveau -> prec=NULL; }
Les listes doublement chainées
insertion après un précédent

void insererApres (Liste* li, Element*


precedent, Objet* objet)) { nouveau -> suivant= precedent -> suivant;
if (precedent == NULL)
precedent -> suivant = nouveau;
insererEnTeteDeListe (li, objet);
nouveau -> prec=precedent;
if (precedent == li->dernier)
li->nbElt++;
insererEnFinDeListe (li,objet);
else { Element* nouveau = CreerElement(); }
nouveau->data=objet; }
precedent -> suivant ->prec=nouveau;
Les listes doublement chainées
Supprimer un élément

void Supprimer (Liste* li, Objet* objet)) else { r->suiv->prec = r->prec;


{ Element* r= li->premier; int trouver=0; r->prec->suiv = r->suiv; }
while(r!=NULL && !trouver) { free(r);
if (r->data == data) { li->nbElt--; trouver = 1;
if (r->suiv == NULL) { }
li>dernier=r->prec; else {
li->dernier->suiv = NULL;} r = r->suiv;
else if (r->prec == NULL) { }
li->premier = r->suiv; }
li->premier->prec =NULL;} }
Les listes doublement chainées

FIN Chapitre 2

Vous aimerez peut-être aussi