Chap. 1Structures séquentielles : listes linéaires 1.

30
Chap. 1 Structures séquentielles : listes linéaires 1

Transcript of Chap. 1Structures séquentielles : listes linéaires 1.

Page 1: Chap. 1Structures séquentielles : listes linéaires 1.

Chap. 1 Structures séquentielles : listes linéaires

1

Page 2: Chap. 1Structures séquentielles : listes linéaires 1.

Exemple (gestion d'un tableau contenant les références des livres

d'une bibliothèque.)• Ce tableau est rangé dans l'ordre alphabétique.

• Lorsqu'un nouveau livre est acheté, son insertion dans le tableau en respectant l'ordre requiert de déplacer toutes les références qui suivent la position d'insertion, pour dégager de la place.

• Pour éviter ce type de problème, il faudrait que le passage d'une case d'un tableau à la suivante ne se fasse plus à partir d'un indice absolu qu'on incrémente, mais en notant localement dans une case du tableau l'indice de la case suivante.

2

Page 3: Chap. 1Structures séquentielles : listes linéaires 1.

On organise en liste linéaire des donnéess qui doivent être traitées séquentiellement.

De plus une liste est évolutive, c.à.d. qu'on veut pouvoir ajouter et supprimer des donnéess.

3

Page 4: Chap. 1Structures séquentielles : listes linéaires 1.

Les listes : définition

• Une liste linéaire est une structure de donnéess correspondant à une suite d'éléments.

• Les éléments ne sont pas indexés dans la liste, mais pour chaque élément (sauf le dernier) on sait où se trouve l’élément suivant.

• Par conséquent, on ne peut accéder à un élément qu’en passant par le premier élément de la liste et en parcourant tous les éléments jusqu’à ce qu’on atteigne l’élément recherché.

4

Page 5: Chap. 1Structures séquentielles : listes linéaires 1.

La représentation des listes par deux tableaux

• le premier tableau contient les éléments de la liste, dans un ordre quelconque.

• le second tableau est organisé de façon suivante : si la case d’indice i du premier tableau contient l’élément dont le suivant se trouve dans la case d’indice j, alors la case d’indice i de second tableau contient l’entier j.

5

Page 6: Chap. 1Structures séquentielles : listes linéaires 1.

Exemplea d b \0

0 1 2 3 4 5

3 5 2 \0

0 1 2 3 4 5

6

Page 7: Chap. 1Structures séquentielles : listes linéaires 1.

Insertion

• Insérons la lettre « c » dans le premier tableau

c a d b \00 1 2 3 4 5

2 3 5 0 \0

0 1 2 3 4 5

7

Page 8: Chap. 1Structures séquentielles : listes linéaires 1.

La représentation chaînée.

• On utilise des pointeurs pour chaîner entre eux les éléments successifs, et la liste est alors déterminée par l'adresse de son premier élément.

• On va définir des enregistrements (structures) dont un des champs est de type pointeur vers une structure chaînée du même type.

8

Page 9: Chap. 1Structures séquentielles : listes linéaires 1.

Définition d'une structure chaînée.

typedef struct nœud{ T info; struct nœud *suiv; }nœud;

typedef nœud *liste; La liste vide est représentée par le pointeur

NULL.9

Page 10: Chap. 1Structures séquentielles : listes linéaires 1.

aaaaa bb ddd mm

Cette représentation n’impose pas une longueur maximum sur les listes ; elle permet de traiter facilement la plupart des opérations sur les listes : le parcours séquentiel, l'insertion et la suppression d'un élément à une place quelconque, la concaténation de deux listes, se font par une simple manipulation des pointeurs.

10

Page 11: Chap. 1Structures séquentielles : listes linéaires 1.

Variables dynamiques

• C'est une variable dont la place mémoire est allouée en cours d'exécution.

• On ne prend de la place mémoire que lorsqu'on en a besoin.

• Cette place mémoire est allouée explicitement, c.à.d. par une instruction du langage.

• Désallocation est aussi proposée par l'intermédiaire d'une instruction.

11

Page 12: Chap. 1Structures séquentielles : listes linéaires 1.

Exemples d’utilisation

12

Page 13: Chap. 1Structures séquentielles : listes linéaires 1.

1. Rechercher un élément dans une liste chaînée juste pour savoir si cet élément est présent ou non

données : T x, liste présultat de type logique (entier en C) Entête en C : int recherche(T x, liste p) ;

13

Page 14: Chap. 1Structures séquentielles : listes linéaires 1.

{variables locales : logique trouve

trouve fauxTANT QUE ((pNULL) et (trouve=faux)) faire

{SI (p->info = x) ALORS

trouve vraiSINON

p p->suiv /*l'adresse de la structure suivante*/

}retourner trouve }

Rmq : Il n’est pas souhaitable de remplacer la condition trouve=faux dans la boucle TANT QUE par p->infox parce que si p pointe sur NULL, p->info n'existe pas.

14

Page 15: Chap. 1Structures séquentielles : listes linéaires 1.

2. Créer une liste chaînée par ajout successif d'éléments jusqu'à la fin.

données modifiées : liste *pp

Entête en C : void créer(liste *pp);

15

Page 16: Chap. 1Structures séquentielles : listes linéaires 1.

{variables locales : liste cour, temp 

*pp NULLsaisir(x)SI (x fin) ALORS /* fin est une constante de type T */

{reserver(*pp) /* crée un poste et met l'adresse dans *pp */*pp->info x*pp->suiv NULL /* obligé de mettre NULL à chaque fin (même

temporaire) */cour *pp /* cour wagon courant (dernier) auquel on rajoute

qqch, cour reçoit *pp, qui est l'adresse du premier élément*/saisir(x)TANT QUE (x fin) FAIRE

{reserver(temp) /*crée la place mémoire d'un wagon */temp->info xtemp->suiv NULL

1) cour->suiv temp /* création du lien */2) cour temp /* cour doit pointer toujours sur la dernière structure, on garde ainsi l'adresse *pp du début de liste */

saisir(x)}

}}

16

Page 17: Chap. 1Structures séquentielles : listes linéaires 1.

Autre méthode...

TANT QUE (x fin) FAIRE{reserver (cour->suiv) /* idem à reserver(temp);

cour->suiv temp; */cour cour->suivcour->info xcour->suiv NULLsaisir(x)}...

17

Page 18: Chap. 1Structures séquentielles : listes linéaires 1.

2. Supprimer un élément de la liste.

- On suppose que la liste existe

données : T xdonnées modifiées : liste *pprésultat de type logique

/* x=info à supprimer, *pp est une données modifiée, car on peut supprimer le premier de la liste, ok indique si la suppression a eu lieu */

Entête en C : int suppression(T x, liste *pp);

18

Page 19: Chap. 1Structures séquentielles : listes linéaires 1.

{variables locales : liste prec, cour ; logique ok

ok fauxSI (*pp->info = x) ALORS

{prec *pp*pp *pp->suivok vrailiberer(prec) /*suppression du premier

élément */}

19

Page 20: Chap. 1Structures séquentielles : listes linéaires 1.

SINON{prec *ppcour *pp->suivTANT QUE ((ok = faux) et (cour NULL)) FAIRE

{SI (cour->info = x) ALORS /*cour pointe sur celui à

supprimer, prec pointe sur le précédent */{ok vraiprec->suiv cour->suiv /* création du lien entre

celui qui précède un élément à supprimer et celui qui le suit */liberer(cour)

}SINON

{prec cour /* mémorisation de la place

d'élément précédent l'élément à tester */cour cour->suiv

}}

}}

retourner ok}

20

Page 21: Chap. 1Structures séquentielles : listes linéaires 1.

3. Insertion d’un élément dans une liste chaînée triée

données T xdonnées modifiées liste *pp

Entête en C : void insert (T x, liste *pp);

21

Page 22: Chap. 1Structures séquentielles : listes linéaires 1.

{variables locales : ptr_liste cour, prec ; logique trouve

SI (*pp = NULL) ALORS {reserver(*pp)*pp->info x*pp->suiv NULL}

SINONSI (x < *pp->info) ALORS

{ reserver(cour) cour->info x cour->suiv *pp *pp cour

}

22

Page 23: Chap. 1Structures séquentielles : listes linéaires 1.

SINON{trouve fauxprec *ppcour *pp->suivTANT QUE ((cour NULL) et (trouve = faux)) FAIRE

{SI (x < cour->info) ALORS

{trouve vrai reserver(prec->suiv)prec prec->suivprec->info xprec->suiv cour}

SINON{ prec cour cour cour->suiv}

}

23

Page 24: Chap. 1Structures séquentielles : listes linéaires 1.

SI (cour = NULL) ALORS{ reserver (prec->suiv)cour prec->suivcour->info xcour->suiv NULL}

}}

24

Page 25: Chap. 1Structures séquentielles : listes linéaires 1.

4. Suppression d’un élément d’une liste chaînée triée

données : T xdonnées modifiées : liste *pprésultat de type logique

Entête en C : int suppr (T x, liste *pp);

25

Page 26: Chap. 1Structures séquentielles : listes linéaires 1.

{variables locales : ptr_liste cour, prec ; logique trouve

trouve fauxSI (*pp NULL) ALORS

SI (x = *pp->info) ALORS{

cour *pp *pp *pp->suiv

liberer (cour)trouve vrai}

26

Page 27: Chap. 1Structures séquentielles : listes linéaires 1.

SINON{prec *ppcour *pp->suivTANT QUE ((trouve = faux) et (cour NULL))

FAIRE{SI (x = cour->info) ALORS

{prec->suiv cour->suivliberer (cour)trouve vrai}

SINONSI (x > cour->info) ALORS

{ prec cour cour cour->suiv }SINON cour NULL

} }

retourner trouve}

27

Page 28: Chap. 1Structures séquentielles : listes linéaires 1.

Il existe d'ailleurs de nombreuses variantes de la représentation des listes à l'aide de pointeurs

a) Il est parfois commode de définir une liste non pas comme un pointeur sur une cellule, mais par un bloc de cellules du même type que les autres cellules de la liste. Ce bloc ne contient que l'adresse du premier élément de la liste. L'utilisation d'un tel bloc permet d'éviter un traitement spécial pour l'insertion et la suppression en début de liste.

b) On peut aussi créer des listes circulaires : on remplace, dans la dernière place de la liste, le pointeur à NULL par un pointeur vers la tête de la liste ; de plus si l'on choisit la dernière place comme point d'entrée dans la liste, on retrouve la tête de liste en parcourant un seul lien.

c) Dans la représentation classique, le parcours des listes est orienté dans un seul sens : du premier élément vers le dernier élément. Cependant de nombreuses applications nécessitent de parcourir les listes à la fois vers l'avant et vers l'arrière, et dans ce cas on peut faciliter le traitement en rajoutant des "pointeurs arrière", ce qui augmente évidemment la place mémoire utilisée. On obtient alors une liste doublement chaîné : chaque place comporte un pointeur vers la place suivante et un pointeur vers la place précédente.

28

Page 29: Chap. 1Structures séquentielles : listes linéaires 1.

Exemple d'utilisation d'une liste chaînée bidirectionnelle

29

typedef struct doub{ T info ;struct doub *suiv, *prec ;

} doub ;

typedef doub *liste_doub ;

Page 30: Chap. 1Structures séquentielles : listes linéaires 1.

30

Afficher le contenu d'une liste à l'envers.

données : liste_doub p

Entête en C : void afficher(liste_doub p);

{SI p NULL ALORS{TANT QUE (p->suiv NULL) FAIRE

p p->suivTANT QUE (p NULL) FAIRE

{afficher (p->info)p p->prec}

}}