1
Structures de données
0 1 2 3 4 5 6
3
• Recourt à des allocations dynamiques
de la mémoire avec la précision de la
dimension.
• En langage C, les tableaux offrent un
moyen statique de stockage
4
Une nouvelle structure
Objectifs recherchés :
5
Listes chainées
6
Liste chainée
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.
Structure tableau :
T[1] T[2] T[3]
T A B C
8
Structuration des éléments
Pour que chaque élément arrive à avertir un
autre élément, il faut qu’il ait son adresse
A B
D
C
F
E
Liste chainée
Composition :
cellule
Donnée Donnée
Donnée
Donnée
Donnée
Lien
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. Il faut passer par les
précédents
1
Cette linéarité est virtuelle. 8
Liste chainée
Repérage des cellules :
Précédente
Tête
Donnée Donnée
Donnée
Donnée
Donnée
Suivante
1
9
Démarche
….
Jusqu’à ce queue
2
Représentation en C
…
Premier Dernier
élément élément
?
Représentation en C
Information
s de
l’élément
Adresse du
suivant
Élément
Représentation en C
Information
1
s de
l’élément Donnée complexe
Adresse du
2
suivant
struct
element ?
{
type1 partie1
type2
?
partie2
Représentation en C
Information
1
s de
l’élément
Adresse du suivant 2
typdef struct element
{
int info; 1
struct element *suivant; 2
}
liste;
Algorithmes complexes
Il reste à structurer la
liste ?
Représentation en C
information
@suivant
information
@suivant
information
@suivant
… information
@suivant
information
@200
information
@300
information
@xxx
… information
@null
1. Insertion
2. Affichage
3. Suppression
Liste chainée
Ajouter/Suppression :
Cellule
Donnée Donnée
Donnée
Cellule Donnée
Donnée
Cellule
Exemple 1
Problème
Construire une liste chainée (L) qui contiendra
l’ensemble d’entier {7,5,13,9}
Algorithmes complexes
Le problème de
construction d’une liste
chainée se résume en un
problème d’insertion
Exemple 1
Représentation graphique de la liste chainée
Adresse du suivant
7 5 13 9
L
12 15 17 18 NULL
Nouveau Où l’insérer
Début
Milieu
3
Fin 6
Algorithmes complexes
Il faut toujours se
rappeler de L
3
7
Insertion d’un nouveau élément dans la liste
Au début de la liste
NULL
Créer nouveau
nouveau-
>suivant=L;
L=nouveau;
Insertion d’un nouveau élément dans la liste
À la fin de la liste
e1 e2 e3 e4 Nouveau NULL
Créer nouveau
Aller jusqu’à la fin de la liste (position=e4)
// à l’aide d’un autre pointeur *temp pour ne pas perdre L
position->suivant=nouveau;
nouveau->suivant=NULL; // obligatoire pour indiquer la fin de la liste
Le problème revient à se positionner à position 3
9
Insertion d’un nouveau élément dans la liste
En milieu
e1 e2 Nouveau e3 e4
NULL
Créer nouveau
Aller jusqu’à la position souhaitée
// à l’aide d’un autre pointeur *temp pour ne pas perdre L
//ici, position est entre e2 et e3
//ou autrement dit, entre e2 et e2->suivant
nouveau->suivant=e2->suivant;
// attention si e2 est NULL. Si c’est le cas, le
Exemple 1: Solution
Pour construire une liste chainée (L) qui contiendra
l’ensemble d’entier {7,5,13,9}
Exemple 1: Solution
Etape 1: Définir la structure de donnée
4
3
Exemple 1: Solution
int main()
{
element *L;
L=NULL;// L ne contient aucun élément
element *elt;
// élément 1
elt=(element*)malloc(sizeof(element));
elt->info=7;
elt->suivant=L;
L=elt;
// élément 2
elt=(element*)malloc(sizeof(element));
elt->info=5;
elt->suivant=L;
L=elt;
// élément 3
elt=(element*)malloc(sizeof(element));
elt->info=13;
elt-
>suivant=L;
L=elt;
// élément 4
elt=(element*)malloc(sizeof(element));
elt->info=9;
elt- 4
4
} >suivant=L;
Exemple 1 : Solution simple
1. Insertion
2. Affichage
3. Suppression
Affichage des éléments de la liste
Il suffit de connaitre L …
e1 e2 e3 e4 NULL
1. Insertion
2. Affichage
3. Suppression
Affichage des éléments de la liste
Il suffit de connaitre L …
e1 e2 e3 e4 NULL
À Il se trouve où ?
supprimer
Début
Milieu
Fin
Suppression d’un élément de la liste
Exercice 2
Modification de données.
Visualisation de l'information enregistrée dans une
cellule.
Visualisation de toutes les informations
enregistrées.
Suppression d'une cellule.
Ajout d’une cellule.
PS
cellule *PS
PS=PP
Manipulation d’une liste chainée
Les basiques :
Se positionner sur la dernière cellule :
return ps;
}
Manipulation d’une liste chainée
Les basiques :
Une liste vide est une liste chaînée qui ne contient
aucun élément :
PP
Tête de liste.
Reste de
Fin de liste. Donnée
la liste
Cellule
Donnée
Cellule
5
9
Manipulation d’une liste chainée
Ajout en tête :
Créer un élément
}
Manipulation d’une liste chainée
Exercice :
Coder la fonction afficher(cellule* p) qui
permet de parcourir une liste et d’afficher son
contenu…
void afficher(cellule *p) {
cellule *curseur;
curseur = p;
while(curseur !=NULL ) {
printf("%d", curseur->info) ;
curseur=curseur->suivant;
}
}
Manipulation d’une liste chainée
Supprimer un élément de tête :
Il s'agit là de supprimer le premier élément de la liste.
Donnée Donnée
Donnée Donnée
}
Manipulation d’une liste chainée
Supprimer un élément en fin de liste :
1 4 5 7
suivant
liste * recherche(int x, liste *l){
liste * CreerCellule(int x) {
liste *c;
c=AlloueCellule();
If (c!=NULL){
c->info=x;
c->suivant=NULL;}
return c;
}
d) Ecrire la fonction : liste * InserEnTete(int x, liste *l)
qui insère une cellule à l’entête de la liste
do{
printf("Donnez un entier 0 pour terminer"\n);
scanf("%d",&x);
if(x) {
c=InserEntete(x,l);
if (c!=NULL) {
c->suivant=l; l=c:}
else return l;
}
} while (x!=0); return c;
f) Ecrire la fonction itérative : liste * InsertOrd_Iter(int x, liste *l)
qui permet d’insérer une cellule en respectant l’ordre
décroissant des valeurs
if (l)
{ printf("%d\n",l->info);
affiche_Recur(l->suivant);}
}
k) Ecrire une fonction itérative : void affiche_Iter(liste *l)
qui affiche tous les cellules de la liste
void affiche_iter(liste(*l){
liste *c;
c=l;
while(c)
{ printf("%d\n",l->info);
c=c->suivant;
}
}
l) Ecrire la fonction récursive : void affiche_Inv_Recur(liste *l)
qui affiche en ordre inverse tous les cellules de la liste
return l;}
n) Ecrire la fonction récursive :
liste * supprim_Un_Recur(int x, liste *l)
qui supprime un élément x de la liste
scanf("%d",&choix);
switch (choix)
{
case 0 : break;
case1 : printf("donner l'entire:");scanf("%d",&x);
l=InserEntete(x,l);break;
case 2: l=Inser_Successives(l);break;
default: break;
}
}while choix;}
Définir la structure d'une Liste doublement chaînée
list *allouer () {
return (liste*)malloc(sizeof(liste));
}
créer une cellule dans la liste
liste * creecellule(int x) {
liste *c;
c=allouer();
if (c!=NULL) {
c->suivant=NULL;
c->precedent=NULL;}
return c
insérer à l'entête
}
LES LISTES CIRCULAIRES
Une liste circulaire est une liste telle que le dernier élément
de la liste contient un pointeur sur le premier
1) Créer cette liste:
liste *creerListe(liste *last, int data)
2) Ajouter une cellule au début de la liste
liste *ajoutDebut(liste *last, int data)
3) Ajouter une cellule à la fin:
liste *ajouterFin(liste *last, int data)
4)Ajouter après une cellule de la liste:
liste *ajouterApres(liste *last, int data, int item)
5) une fonction qui parcourt la liste et affiche ses élément:
void traverse(liste *last)
5) Faire un menu qui utilise les 5 fonctions
#include <stdio.h>
#include <stdlib.h>
if (last != NULL)
return last;
return last;
}
liste *ajoutDebut(liste *last, int data)
{
if (last == NULL)
return creerListe(last, data);
return last;
}
liste *ajouterFin(liste *last, int data)
{
if (last == NULL)
return creerListe(last, data);
return last;
}
liste *ajouterApres(liste *last, int data, int item)
{
if (last == NULL)
return NULL;
liste *temp, *p;
p = last -> suivant;
do
{
if (p ->data == item)
{
temp = (liste *)malloc(sizeof(liste));
temp -> data = data;
temp -> suivant = p -> suivant;
p -> suivant = temp;
if (p == last)
last = temp;
return last;
}
p = p -> suivant;
} while(p != last -> suivant);
if (last == NULL)
{
printf("liste vide.\n");
return;
}
do
{
printf(" ..%i ...",p -> data) ;
p = p -> suivant;
}
while(p != last->suivant);
}
int main()
{
liste *last = NULL;
traverse(last);
return 0;
}
Gérer une liste circulaire en utilisant deux pointeurs Tete et Queue
{
int info;
struct Node *suivant;
}node;
node *tete=NULL,*queue=NULL,*temp;
void creer();
void supprimer();
void afficher();
void creer()
{
node *newnode;
newnode=(node*)malloc(sizeof(node));
printf("\nEntrez la valeur : ");
scanf("%d",&newnode->info);
newnode->suivant=NULL;
if(queue==NULL)
tete=queue=newnode;
else
{
queue->suivant=newnode;
queue=newnode;
}
queue->suivant=tete;
}
void supprimer()
{
temp=tete;
if(tete==NULL)
printf("\n une erreur :");
else
{
if(tete==queue)
{
printf("\n%d",tete->info);
tete=queue=NULL;
}
else
{
printf("\n%d",tete->info);
tete=tete->suivant;
queue->suivant=tete;
}
temp->suivant=NULL;
free(temp);
}
}
void afficher()
{
temp=tete;
if(tete==NULL)
printf("\n vide");
else
{
printf("\n");
for(;temp!=queue;temp=temp->suivant)
printf("\n%d addresse=%u suivant=%u\t",temp->info,temp,temp->suivant);
printf("\n%d addresse=%u suivant=%u\t",temp->info,temp,temp->suivant);
}
}
int main()
{int chc;
do
{
printf("\nMenu\n\t 1 creer un element : ");
printf("\n\t 2 supprimer un element : ");
printf("\n\t 3 afficher la liste : ");
printf("\n\t 4 sortir : ");
printf("\n entrez votre choix : ");
scanf("%d",&chc);
switch(chc){
case 1:creer();break;
case 2:supprimer(); break;
case 3:afficher(); break;
case 4: return 1;
default: printf("\nInvalid choice :");}
}while(1);
return 0;
}