Vous êtes sur la page 1sur 19

Chapitre 4

Listes doublement
chaînées

Naoual Nassiri
GI S2
2023-2024
Définition
❑Contrairement aux listes simplement chaînées, la liaison
entre les éléments d’une liste doublement chaînée se fait
grâce à deux pointeurs :
➢Le premier pointe vers l'élément précédent
➢Le deuxième pointe vers l'élément suivant

Un élément d’une Adresse de l’élément précédent


liste doublement = Valeur de l’élément
chainée
Adresse de l’élément suivant

NULL @404 @1248 @152 @566


38 19 71 20 24
@1248 @152 @566 @2160 NULL
Vraies adresses @404 @1248 @152 @566 @2160
Structures de données - N. Nassiri 2
Définition
❑ Le pointeur precedent du premier élément doit pointer vers
NULL (le début de la liste).
❑ Le pointeur suivant du dernier élément doit pointer vers NULL
(la fin de la liste).
❑ Pour accéder à un élément, la liste peut être parcourue dans les
deux sens :
➢ En commençant par le premier élément, le pointeur suivant
permettant le déplacement vers le prochain élément.
➢ En commençant par le dernier élément, le pointeur précédent
permettant le déplacement vers l'élément précédent.

NULL @404 @1248 @152 @566


38 19 71 20 24
@1248 @152 @566 @2160 NULL
Vraies adresses @404 @1248 @152 @566 @2160
Structures de données - N. Nassiri 3
Implémentation de la liste

❑ L’implémentation des listes passe par plusieurs étapes :


➢Création des types structurés pour définir la structure
de données d’un élément de la liste.
➢Définition des fonctions : Initialisation, Ajout,
Suppression, Affichage, ….
➢Déclaration de la liste et appel des fonctions dans le
programme principal main().

Structures de données - N. Nassiri 4


Définition des types structurés
❑ On commence par définir la structure qui représente les
éléments de la liste.
❑ Ensuite, on définit la liste en spécifiant le premier élément
de la liste, son dernier élément et sa taille (Facultatif).
❑ Exemple : Structure de ‘’Element’’ identifié par une
valeur sous forme d’entier.
typedef struct Element typedef struct
{ {
int valeur; Element *debut;
struct Element *precedent; Element *fin;
struct Element *suivant; int taille;
} Element; } Liste;
Fonction définissant la structure Fonction définissant la liste
Structures de données - N. Nassiri 5
Initialisation de la liste

❑ L’initialisation consiste à initialiser les pointeurs


‘’debut’’ et ‘’fin’’ avec le pointeur NULL, et la taille avec
la valeur 0.

void initialisation (Liste *L) {


L->debut = NULL;
L->fin = NULL;
L->taille = 0;
}

Structures de données - N. Nassiri 6


Insertion dans une liste vide
❑ Étapes :
1.Allouer de la mémoire pour le nouvel élément.
2.Remplir le champ de données du nouvel élément.
3.Faire pointer les pointeurs precedent et suivant du
nouvel élément vers NULL.
4.Les pointeurs debut et fin pointent vers le nouvel
élément.
5.Mettre à jour la taille.

Etat initial : Etat final :


debut NULL precedent fin
NULL
fin NULL valeur
NULL
debut suivant
Structures de données - N. Nassiri nouvel élément 7
Insertion dans une liste vide

void ins_listeVide (Liste *L, int n){


Element *nouv_E;
nouv_E=malloc(sizeof(Element));
nouv_E->valeur=n;
nouv_E->precedent = NULL;
nouv_E->suivant = NULL;
L->debut = nouv_E;
L->fin = nouv_E;
L->taille++;
} Structures de données - N. Nassiri 8
Insertion au début de la liste
❑ Étapes:
1. Allouer de la mémoire pour le nouvel élément.
2. Remplir le champ de données du nouvel élément.
3. Le pointeur precedent du nouvel élément pointe vers NULL.
4. Le pointeur suivant du nouvel élément pointe vers le début de
la liste.
5. Le pointeur precedent du premier élément pointe vers le
nouvel élément.
6. Le pointeur debut pointe vers le nouvel élément.
7. Incrémenter la taille.

NULL precedent
debut
valeur valeur ⋯⋯
debut NULL suivant suivant
valeur
suivant
Nouvel élément Structures de données - N. Nassiri 9
Insertion au début de la liste

void ins_debut_liste (Liste *L, int n) {


Element *nouv_Elem;
nouv_Elem =malloc(sizeof(Element));
nouv_Elem ->valeur=n;
nouv_Elem ->precedent=NULL;
nouv_Elem ->suivant=L->debut ;
L->debut->precedent=nouv_Elem;
L->debut=nouv_Elem;
L->taille++; }
Structures de données - N. Nassiri 10
Insertion à la fin de la liste
❑ Étapes:
1. Allouer de la mémoire pour le nouvel élément.
2. Remplir le champ de données du nouvel élément.
3. Faire pointer le pointeur suivant du nouvel élément vers
NULL.
4. Faire pointer le pointeur precedent du nouvel élément vers
le dernier élément.
5. Faire pointer le pointeur suivant du dernier élément vers le
nouvel élément.
6. Faire pointer le pointeur fin vers le nouvel élément.
7. Incrémenter la taille.
precedent precedent fin
valeur valeur
⋯⋯ fin
suivant NULL precedent
valeur
Nouvel
NULL élément
Structures de données - N. Nassiri 11
Insertion à la fin de la liste

void ins_fin_liste (Liste1 *L, int n) {


Element *nouv_Elem =malloc(sizeof(Element));
nouv_Elem->valeur=n;
nouv_Elem->suivant = NULL;
nouv_Elem->precedent= L->fin;
L->fin ->suivant = nouv_ Elem;
L->fin = nouv_ Elem;
L->taille++;
}

Structures de données - N. Nassiri 12


Insertion au rang k de la liste
❑ Étapes:
1. Allouer de la mémoire pour le nouvel élément.
2. Remplir le champ de données du nouvel élément.
3. Identifier l’élément à la position k (l'insertion se fera après cet élément).
4. Pointer suivant du nouveau élément vers l’élément à la position k+1.
5. Pointer le pointeur precedent du nouveau élément vers l’élément courant.
6. Pointer precedent de l’élément à la position k+1 vers le nouveau élément.
7. Pointer le pointeur suivant de l’élément courant vers le nouvel élément.
8. Incrémenter la taille.
Rang k
precedent precedent precedent
⋯⋯ valeur valeur valeur ⋯⋯
suivant suivant suivant

precedent
Nouvel valeur
élément suivant Structures de données - N. Nassiri 13
Insertion au rang k de la liste
void ins_liste (Liste1 *L, int n, int posit){
Element *courant, *nouv_Elem;
int i;
nouv_ Elem=malloc(sizeof(Element));
nouv_ Elem ->valeur=n;
courant = L->debut;
for(i=1; i<posit; i++)
courant = courant->suivant;
nouv_ Elem->suivant = courant->suivant;
nouv_ Elem->precedent = courant;
courant->suivant->precedent= nouv_ Elem;
courant->suivant = nouv_ Elem;
L->taille++;} Structures de données - N. Nassiri 14
Suppression d’un élément de la liste

❑ Dans le cas des listes doublement chaînées, la


suppression à n'importe quelle position ne pose pas de
problèmes grâce aux pointeurs precedent et suivant, qui
permettent d’identifier les positions des éléments de la
liste.
❑ Ainsi, nous allons créer une seule fonction qui permet la
suppression d’un élément donné.

Structures de données - N. Nassiri 15


Suppression de l’élément au rang k
void supp_dans_liste (Liste1 *L, int rang){
Element *courant, int i;
courant = L->debut;
for (i = 1; i < rang; ++i)
courant = courant->suivant;
if(courant->precedent==NULL) (// Suppression au début)
{ courant->suivant->precedent = NULL;
L->debut = courant->suivant;}
else if(courant->suivant ==NULL) (// Suppression en fin de liste)
{ courant->precedent->suivant = NULL;
L->fin=courant->precedent;}
else (// Suppression au milieu de la liste)
{ courant->precedent->suivant = courant->suivant;
courant->suivant->precedent = courant->precedent;}
free (courant);
L->taille--; } Structures de données - N. Nassiri 16
Affichage de la liste

❑ L’affichage d’une liste doublement chainée peut se faire


de deux manières :
➢ Affichage à partir du début de la liste : du premier
élément au dernier élément
➢ Affichage à partir de la fin de liste : du dernier au
premier élément

Structures de données - N. Nassiri 17


Affichage de la liste à partir du
début de la liste
void afficherListeApartirDebut(Liste *L) {
Element * courant ;
courant = L->debut;
printf("Affichage de la liste à partir du début:\n");
while (courant!=NULL) {
printf("%d\n", courant->valeur);
courant = courant->suivant;
}
}
Structures de données - N. Nassiri 18
Affichage de la liste à partir de la
fin de la liste
void afficherListeApartirFin(Liste *L) {
Element * courant ;
courant = L->fin;
printf("Affichage de la liste à partir de la fin :\n");
while (courant!=NULL) {
printf("%d\n", courant->valeur);
courant = courant->precedent;
}
}
Structures de données - N. Nassiri 19

Vous aimerez peut-être aussi