Telechargé par criminasser

chapitre 02 LISTE CHAINEE

publicité
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
15/02/2023
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
15/02/2023
Liste Chainée
4
Exemple de problème à résoudre
PR M.EL FAR
15/02/2023
Liste Chainée
5
Résolution du problème
Principe de base
chaque élément peut avertir son suivant
Tableaux ?
Nombre d’éléments inconnu
méthode à écarter
Liste chainée ?
Méthode adoptée pour les tailles dynamiques
PR M.EL FAR
15/02/2023
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
15/02/2023
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
15/02/2023
Liste Chainée
8
Représentation en C
PR M.EL FAR
15/02/2023
Liste Chainée
9
li -> premier
li -> dernier
3
li
liste
li -> nbElt
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;
// Un élément de la liste
typedef struct element {
Objet *data;
struct element* suivant;
} Element;
// Le type liste
typedef struct {
Element *premier;
Element *dernier;
int nbElt;
} Liste;
Les principales opérations sur une liste chainée
L’interface List.h
#ifndef LISTE_H
#define LISTE_H
// definition de type boolean avec vrai et faux
#define faux 0
#define vrai 1
typedef int boolean;
typedef void Objet;
// un élément de la liste
typedef struct element {
Objet*data;
struct element *suivant;
} Element;
// le type Liste
typedef struct {
Element *premier;
Element *dernier;//optionnel
int nbElt;
} Liste;
//les opérations sur la liste
void initListe(Liste *li);
Liste* creerListe();
boolean listeVide(Liste *li);
void insererEnTeteDeListe(Liste *li,Objet *o);
void insererEnFinDeListe(Liste *li,Objet *o);
Objet* extraireEnTeteDeListe (Liste* li);
Objet* extraireApres(Liste* li,Element* precedent);
Objet* extraireEnFinDeListe (Liste* li);
// parcours de la liste
void listerListe(Liste *li,void (*f) (Objet*));
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
void initListe(Liste *li)
{
li->premier =NULL;
li->dernier =NULL;
li->nbElt=0;
}
// Création de la liste
Liste* creerListe()
{
Liste* li;
li=(Liste*)malooc(sizeof(Liste));
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
List *li;
li -> dernier
3
li -> nbElt
Ajout en tête
3
4
li
data
1
objet
Data
2
data
3
null
li -> premier = nouveau;
nouveau -> suivant = li -> premier;
li -> nbElt ++;
Nouveau
// Création du nouveau element
nouveau -> suivant = li -> premier;
void insererEnTeteDeListe (Liste* li, Objet* objet)
{Element* nouveau;
li -> premier = nouveau;
nouveau=(Element*)malloc(sizeof(Element));
if (li->dernier == NULL)
li -> dernier = nouveau;
nouveau->data=objet;
li -> nbElt ++;
Ajout après un précédent
4
3
li
précédent
data
1
objet
Nouveau
void insererApres (Liste* li, Element*
precedent, Objet* objet)) {
if (precedent == NULL) {
insererEnTeteDeListe (li, objet);}
else {
Element* nouveau = CreerElement();
nouveau->data=objet;
Data
2
Précédent -> suivant
data
3
precedent -> suivant = nouveau;
nouveau -> suivant= precedent -> suivant;
li -> nbElt ++;
nouveau -> suivant= precedent -> suivant;
precedent -> suivant = nouveau;
if (precedent == li->dernier)
li->dernier = nouveau;
li->nbElt++;
} }
null
Ajout en fin de liste
li
3
4
data
1
Data
2
data
3
li-> dernier -> suivant = nouveau;
objet
Nouveau
Void insererFinListe(Liste*li,Objet* objet) {
Element* nouveau = CreerElement();
Else {
li-> dernier -> suivant = nouveau;
nouveau->data=objet;
li->dernier = nouveau;
li->nbElt++;
if (li->premier == NULL)
insereren TeteListe(Liste*li,Objet* objet);
}
null
Supprimer un élément en tête de liste
3
2
li
data
1
Extrait
Objet* extraireEnTeteDeListe (Liste* li) {
Element* extrait = li->premier;
if (!listeVide(li)) {
li -> premier = li -> premier -> suivant;
if (li->premier==NULL) // Liste devenue vide
li -> dernier=NULL;
li->nbElt--;}
return extrait != NULL ? extrait->reference : NULL;
}
Data
2
data
3
null
Element* extrait = li -> premier;
li -> premier = li -> premier ->
suivant;
Supprimer un élément en tête de liste
Supprimer un élément en tête de liste
3
2
li
data
1
Extrait
Data
2
data
3
Liste* SupprimerTeteDeListe (Liste* li) {
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; }
null
Supprimer un élément en Fin de liste
Supprimer un élément en Fin de liste
li
3
2
data
1
Data
2
Liste* extraireFinDeListe (Liste* li) {
data
3
NULL
Element *e= li->premier;
if (listeVide(li)) { return li;}
If(li->nbElt==1) {
free(li); li->nbElt--;
return NULL;}
while(e ->suiv ->suiv!=NULL)
free(e ->suiv);
li ->derneir=e;
e ->suiv=NULL;
li->nbElt--;
return li;}
e=e ->suiv;
null
Extrait
Les listes doublement chainées
Les listes doublement chainées
Les listes doublement chainées
25
li -> premier
li -> dernier
li -> nbElt
3
li
liste
a
b
c
Liste Doublement
Chaînée
cellule
typedef void Objet;
// un élément de la liste
typedef struct element {
Objet*data;
struct element *suivant;
struct element *precedent;
} Element;
// le type Liste
typedef struct {
Element *premier;
Element *dernier;//optionnel
int nbElt;
} Liste;
Initialisation et création d’une liste
Doublement Chainée
// Initialisation de la liste
void initListe(Liste *li)
{
li->premier =NULL;
li->dernier =NULL;
li->nbElt=0;
}
// Création de la liste
Liste* creerListe()
{
Liste* li;
li=(Liste*)malooc(sizeof(Liste));
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
// Création du nouveau element
void insererEnTeteDeListe (Liste* li, Objet* objet) {
Element* nouveau;
nouveau=(Element*)malloc(sizeof(Element));
li -> premier = nouveau;
li -> dernier = nouveau; }
Else{
li -> premier ->prec=nouveau;
nouveau -> suivant= li -> premier ;
nouveau -> suiv=NULL;
li -> premier=nouveau;
nouveau -> prec=NULL
nouveau->data=objet;
if (li->dernier == NULL) {
}
li -> nbElt ++;
}
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 ++;
}
Les listes doublement chainées
insertion après un précédent
void insererApres (Liste* li, Element* precedent,
Objet* objet)) {
if (precedent == NULL)
insererEnTeteDeListe (li, objet);
if (precedent == li->dernier)
insererEnFinDeListe (li,objet);
nouveau -> suivant= precedent -> suivant;
precedent -> suivant = nouveau;
nouveau -> prec=precedent;
li->nbElt++;
else{Element*nouveau= CreerElement(objet);
}
precedent -> suivant ->prec=nouveau;
}
Les listes doublement chainées
Supprimer un élément
void Supprimer (Liste* li, Objet* data))
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
Téléchargement