Vous êtes sur la page 1sur 21

Le langage C

Structures de données

Les listes
simplement chaînées
Plan
• Principe
• Liste chaînée Vs. Tableau
• Construction
• Parcours
• Insertion
• Suppression
• Fonctions de manipulation
Principe
Notion de maillon
L'élément de base d'une liste chaînée
s'appelle le maillon.
Il est constitué :
* d'un champ de données ;
* d'un pointeur vers un maillon.

données
pointeur
Principe
Maillon suivant
Le champ pointeur vers un maillon
pointe vers le maillon suivant de la liste.
S'il n'y a pas de maillon suivant, le
pointeur vaut NULL.
Principe
Notion de liste
Une liste simplement chaînée est un
pointeur sur un maillon. Une liste vide
est une liste qui ne contient pas de
maillon. Elle a donc la valeur NULL.

NULL
Principe
La terminologie suivante est généralement employée :
* le premier maillon de la liste est appelé tête ;
* le dernier maillon de la liste est appelé queue.

NULL

tête queue

Rq : il se peut que les maillons qui composent la liste ne


soit pas placées dans l'ordre en mémoire et encore moins
de façon contiguë.
Liste chaînée Vs. Tableau
Dans une liste chaînée :
– la taille est inconnue au départ, la liste peut avoir autant
d'éléments que votre mémoire le permet.
– Pour déclarer une liste chaînée il suffit de créer le
pointeur qui va pointer sur le premier élément de votre
liste chaînée, aucune taille n'est à spécifier donc.
– Il est possible d'ajouter, de supprimer, d'intervertir des
éléments d'un liste chaînées en manipulant simplement
leurs pointeurs.
Construction
Le maillon
Il faut déclarer les types constituant le
maillon. Exemple :
//pointeur sur maillon
typedef struct s_maillon *p_maillon_t;
//maillon
typedef struct s_maillon {
int valeur;
p_maillon_t suivant;
} maillon_t;
Construction
La liste
Maintenant on déclare les types
constituant la liste :
//liste
typedef p_maillon_t liste_t;

//pointeur sur liste


typedef liste_t *p_liste_t;
Construction
Deux types de fonctions vont interagir avec les listes :
* les fonctions qui utilisent les listes :
elles voient l'aspect externe des listes
(les types liste_t et p_liste_t)

* les fonctions qui gèrent les listes :


elles voient l'aspect interne des listes
(les types maillon_t et p_maillon_t).

Les fonctions qui utilisent les listes n'ont pas à savoir que
les listes sont constituées de maillons.
Parcours
D’après son principe et sa construction, le
parcours d’une liste simplement chaînée se
fait uniquement du début vers la fin.
Illustrons ceci par le calcul de la longueur
d’une liste simplement chaînée.

NULL
Parcours
Longueur de la liste
* Version itérative :
int longueur_i(liste_t liste)
{
p_maillon_t p_maillon = liste;
int longueur = 0;
while (p_maillon != NULL)
{
longueur++;
p_maillon = p_maillon->suivant;
}
return longueur;
}
Parcours
Longueur de la liste
* Version récursive :
int longueur_r(liste_t liste)
{
p_maillon_t p_maillon = liste;
if (p_maillon != NULL)
{
return 1 +
longueur_r(p_maillon->suivant);
}
return 0;
}
Parcours
Exercice : (correction en TP)
Affichage de la liste.
Écrire les fonctions permettant l’affichage
du contenu de la liste en version itérative et
récursive.
Insertion
Insertion en tête
Insertion
Insertion en tête
void insertion_en_tete(p_liste_t p_liste, int entier)
{
p_maillon_t p_maillon_ancien = *p_liste;
p_maillon_t p_maillon_nouveau = NULL;
p_maillon_nouveau = malloc(sizeof(maillon_t));
p_maillon_nouveau->valeur = entier;
p_maillon_nouveau->suivant = p_maillon_ancien;
*p_liste = p_maillon_nouveau;
}
Insertion
Insertion en queue
Insertion
Insertion en queue (version récursive)

void insertion_en_queue(p_liste_t p_liste, int entier)


{
p_maillon_t p_maillon = *p_liste;
if (p_maillon == NULL)
{
insertion_en_tete(p_liste, entier);
}
else
{
insertion_en_queue(&(p_maillon->suivant), entier);
}
}
version itérative en exercice
Suppression
Suppression en tête
int suppression_en_tete(p_liste_t p_liste)
{
p_maillon_t p_maillon = *p_liste;
int resultat = 0;
if (p_maillon != NULL)
{
resultat = p_maillon->valeur;
*p_liste = p_maillon->suivant;
free(p_maillon);
}
return resultat;
}
Suppression
Suppression en queue (version récursive)
int suppression_en_queue(p_liste_t p_liste)
{
p_maillon_t p_maillon = *p_liste;
int resultat = 0;
if (p_maillon != NULL)
{
if (p_maillon->suivant == NULL)
{
resultat = suppression_en_tete(p_liste);
}
else
{
resultat =
suppression_en_queue(&(p_maillon->suivant));
}
}
return resultat;
}
version itérative en exercice
Fonctions de manipulation
Au vu de l'utilisation des listes chaînées, il se dessine
clairement quelques fonctions indispensables :

* Initialisation (à vide)
* Ajout d'un élément (à un emplacement i)
* Suppression d'un élément (ième élément)
* Accès à l'élément suivant
* Accès aux données
* Accès au premier élément de la liste
* Accès au dernier élément de la liste
* Suppression de la liste entière

À préparer pour le TP

Vous aimerez peut-être aussi