Vous êtes sur la page 1sur 25

Les listes chaînées

 Les listes doublement chaînée


 Dans une liste doublement chaînée un maillon est composé de trois
champs:
 Un champ de données ;
 Un pointeur vers un le maillon suivant.
 Un pointeur vers un le maillon précédent.

 Suivant : Ce champ pointe vers le maillon suivant de la liste.


S'il n'y a pas de maillon suivant, le pointeur vaut NIL.
 Précédent : Ce champ pointe vers le maillon précédent de la
liste. S'il n'y a pas de maillon précédent, le pointeur vaut NIL.
Les listes chaînées
 Le type liste doublement chaînée
type
maillon = Enregistrement En C
typedef struct maillon{
Valeur : entier int valeur;
suivant : ^maillon struct maillon*suivant;
struct maillon*precedent;
précédent : ^maillon }listedc;
FinEnregistrement
// Définition du type listedc
listedc =maillon
Les listes chaînées
 Insertion d’une valeur en tête d’une liste doublement
chainée.
 Écrire la procédure InserTete qui permet d’insérer une valeur v
en tête d’une liste doublement chaînée donnée par l’adresse de
son premier élément (premier).
 Après l’insertion la valeur du premier sera changée donc le
passage doit se faire par adresse.
Les listes chaînées
 Principe
// Créer un maillon d’adresse nouvElt contenant la valeur v et dont le pointeur
précédent est nil (il sera le premier).
nouvElt ← nouveau(^listedc)
nouvElt ^.valeur ← v
nouvElt ^.précédent ← Nil
// Créer un lien entre le nouveau maillon et la tête de la liste de telle sorte que
premier soit le suivant de nouvElt
nouvElt ^.suivant ← premier
// Créer un lien entre la tête de la liste (si elle existe) et le nouveau maillon de telle
sorte que nouvElt soit le précédent de premier.
Si (premier<>nil) alors
premier^.précèdent ← nouvElt
Finsi
//Le maillon nouvElt devient le premier maillon de liste premier
premier ← nouvElt
Les listes chaînées
 Algorithmique
PROCEDURE InsertTete(var premier : ^listedc, v : entier)
var
nouvElt : ^listedc
Debut
nouvElt ← nouveau(^listedc)
nouvElt ^.valeur ← v
nouvElt ^.précédent ← Nil
nouvElt ^.suivant ← premier
si(premier <>nil) alors
premier ^.précédent ← nouvElt
Finsi
premier ← nouvElt
Fin
Les listes chaînées
 En C
listedc* InsertTete(listedc *premier, int v){
listedc *nouvElt;
nouvElt =(listedc*)malloc(sizeof(listedc));
nouvElt->valeur=v;
nouvElt->precedent=NULL;
nouvElt->suivant= premier;
if(premier!=NULL)
premier ->precedent=nouvElt;

premier =nouvElt;
return premier;
}
Les listes chaînées
 Suppression du premier maillon d’une liste
doublement chaînée
 Écrire la procédure SuppTete qui permet de supprimer le premier
maillon d’une liste doublement chaînée donnée par l’adresse de
son premier élément (premier).
 Après la suppression, la valeur du premier maillon doit changer,
donc le passage doit se faire par adresse.
Les listes chaînées
 Principe
// Si la liste est non vide : on sauvegarde premier dans une variable P1
Si(premier ≠ Nil) alors
P1 ← premier
// La valeur de premier prend la valeur de son suivant.
premier ← premier^.suivant
// La valeur du précédent prend la valeur nil
premier^.précédent ← Nil
// On libère la zone mémoire d’adresse P1.
libérer(P1)
Finsi
Finsi
Les listes chaînées
 Algorithme
PROCEDURE SuppTete (var p : ^listedc)
var
P1: ^listedc
Début
P1 ← p ;
si (p<>nil) alors
p ← p^.suivant
p^.prec ← nil
libérer(P1)
fin si
fin
Les listes chaînées
 En C
listedc* SuppTete (listedc *premier ){
listedc * p1;
p1 ← premier ;
if (premier!=NULL){
premier = premier->suivant ;
premier->precedent = NULL ;
free(p1) ;
}
}
Les listes chaînées
 Les listes circulaires
 Une liste où le pointeur nil du dernier élément est remplacé par
l’adresse du premier élément est appelée liste circulaire.
 Dans une liste circulaire tous les maillons sont accessibles à partir de
n’importe quel autre maillon.
 Une liste circulaire n’a pas de premier et de dernier maillon. Par
convention, on peut prendre le pointeur externe de la liste vers le
dernier élément et le suivant serait le premier élément de la liste.
Les listes chaînées
 Exercice : liste doublement chaînées
 Nous définissons:
 struct monome_elem{
int degre ;
double coef ;
};
typedef struct monome_elem ∗monome ;
 La structure struct monome_elem sera utilisée pour représenter un terme
d'un polynôme. Un polynôme sera codé avec une liste doublement chaînée.
Le type polynome est le suivant :
struct elem {
struct elem ∗ suivant ;
struct elem ∗ precedent ;
monome pval ;
};
typedef struct elem ∗ polynome ;
Les listes chaînées
 Exercice : liste doublement chaînées

1. Ecrire la fonction : polynome tab_to_poly(int n,double tab[]) qui prend en


argument un tableau tab de n éléments et construit un polynome tel que pour
tout indice i, tab[i] est le coefficient du monôme xi .

2. Ecrire la fonction : double * poly_to_tab(polynome p) qui à partir d'un polynôme


p construit un tableau de ses coefficients et retourne un pointeur vers le premier
élément de ce tableau.

3. Ecrire la fonction : polynome supprimer_ieme(polynome p, int i) qui supprime le


monôme de degré i du polynôme p.

4. Ecrire la fonction : polynome derivee(polynome p) qui retourne la dérivée du


polynôme p.

5. Ecrire la fonction : polynome add(polynome p, polynome q) qui retourne la


somme des polynômes p et q. Les listes de p et q ne doivent pas être modifiées.
Les piles
Les piles
 Définition et exemple
 Une pile est une liste ordonnée sans fin d’éléments dans laquelle on
ne peut introduire ou enlever un élément qu'à une extrémité appelée
tête de pile ou sommet de pile.
 Exemple
 une pile de livres
 une pile d’assiettes,
 Dans une pile, le dernier élément inséré sera le premier à être
supprimé, (retiré) : on parle de liste LIFO (Last In First Out).
 Opérations sur les piles
 Les opérations de base sur les piles sont :
 Empiler (p,e) (en anglais push) : empile l’élément e dans la pile p
 Dépiler (p) (en anglais pop): dépile un élément de la pile et retourne la
valeur de cet élément (e ← Depiler (p))
Les piles
 Il n’y a aucune limite au nombre d’éléments qu’on peut empiler. Par contre, on ne peut
dépiler d’une pile vide. A cet effet, on a une fonction PileVide(p) qui retourne Vrai si la
pile est vide sinon Faux.
 InitialiserPile(p) : vide la pile p
 On peut connaître le sommet de pile sans le supprimer SommetDePile(p).
 e ← SommetDePile(p)
 Implémentation d’une pile par liste chaînée
 L’implémentation d’une pile par une liste (simplement) chaînée est une version simplifiée de celle d’une
liste par liste chaînée:
type
maillon = Enregistrement En C
valeur : entier typedef struct maillon{
suivant : ^maillon int valeur;
Fin maillon struct maillon*suivant;
liste : maillon }liste;
Pile =Enregistrement
sommet : ^liste
typedef struct pile{
liste *sommet;
Fin Pile
}Pile;
Les piles
 Les opérations sur une pile void InitialiserPile(Pile *p){
PROCEDURE InitialiserPile(var p : ^Pile)
p->sommet=NULL;
Debut
p^.sommet← Nil }
Fin
*********************************************************************************************************************************

FONCTION PileVide(p : ^Pile) : booléen


Debut
int PileVide(Pile *p){
si ( p^.sommet =Nil) alors
if(p->sommet==NULL)
Retourner vrai return 1;
Sinon else
Retourner faux return 0;
fin si }
Fin
Les piles
 Les opérations sur une pile
PROCEDURE Empiler (var p : ^Pile, e : entier)
Debut
InsertTete(p^.sommet,e)
Fin nouvElt ← nouveau(^liste)
nouvElt ^.valeur ← e
nouvElt ^.suivant ← p^.sommet
p^.sommet ← nouvElt
Les piles
 Les opérations sur une pile

void Empiler(Pile *p, int e){


liste *nouvElt;
nouvElt=(liste*)malloc(sizeof(liste*));
nouvElt->valeur=e;
nouvElt->suivant=p->sommet;
p->sommet=nouvElt;
}
Les piles
 Les opérations sur une pile
FONCTION Dépiler (var p : ^Pile) : entier
var
e : entier
Debut
si (PileVide(p)) alors
Ecrire ("la pile est vide")
sortir
sinon
e ← p^.sommet^.valeur
SuppTete(p)
retourner e Si (p <> Nil) alors
aux ← p^.sommet
finsi
p^.sommet← p^.sommet^.suivant
Fin liberer(aux)
Finsi
Les piles
 Les opérations sur une pile

int Depiler(Pile *p){


int e;
liste *aux;
if(PileVide(p)==1){
printf("pile vide");
exit(0);
}else{
e=p->sommet->valeur;
aux=p->sommet;
p->sommet=p->sommet->suivant;
free(aux);
return e;
}
}
Les piles
 Les opérations sur une pile
FONCTION SommetDePile (p : ^Pile) : entier
Debut
si (PileVide(p)) alors
ecrire ("la pile est vide")
sinon
retourner p^.sommet^.valeur
finsi
Fin
Les piles
 Les opérations sur une pile

int SommetDePile(Pile *p){


if(PileVide(p)==1){
printf("pile vide");
exit(0);
}else{
return p->sommet->valeur;
}
}
Les piles
 Exercice : Utilisation d'une pile, pour le calcul des expressions écrites
en "postfixé«
L'expression dite "infixée" (4+5)*6 s'écrit en "postfixé 4 5 + 6*
On utilise alors une pile pour pouvoir effectuer les calculs.
Les règles d'utilisation sont alors les suivantes:
Si on rencontre
- un nombre : on l'empile
- une opération : on dépile le sommet et le sous sommet
on effectue le calcul sous-sommet "opération" sommet
on empile le résultat

Pour simplifier, on supposera que les opérandes numériques sont donnés sur un seul
chiffre de 0 à 9.
Les piles
 Exercice : Utilisation d'une pile, pour le calcul des expressions écrites
en « postfixé »
Pour ce faire :
– créer une fonction qui teste si un caractère c donné en paramètre est
une opération arithmétique('+','-','*','/').
– créer une fonction qui calcule le résultat de l'opération a op b
(avec op = '+','-','*' ou '/'), les deux opérandes et l’opération sont donnés
en paramètre.
– créer une fonction qui évalue une expression en postfixé donnée en
paramètre sous forme de chaîne caractère.
– tester la fonction d’évaluation dans le programme principal.

Vous aimerez peut-être aussi