La présentation est en train de télécharger. S'il vous plaît, attendez

La présentation est en train de télécharger. S'il vous plaît, attendez

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

Présentations similaires


Présentation au sujet: "Chap. 1 Structures séquentielles : listes linéaires"— Transcription de la présentation:

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

2 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.

3 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.

4 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é.

5 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.

6 Exemple a d b \0 3 5 2 \0

7 Insertion Insérons la lettre « c » dans le premier tableau c a d b \0
2 3 5 \0

8 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.

9 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.

10 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.

11 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.

12 Exemples d’utilisation

13 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 p résultat de type logique (entier en C) Entête en C : int recherche(T x, liste p) ;

14 {variables locales : logique trouve trouve  faux
TANT QUE ((pNULL) et (trouve=faux)) faire { SI (p->info = x) ALORS trouve  vrai SINON 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->infox parce que si p pointe sur NULL, p->info n'existe pas.

15 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);

16 { variables locales : liste cour, temp  *pp  NULL saisir(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*/ TANT QUE (x  fin) FAIRE reserver(temp) /*crée la place mémoire d'un wagon */ temp->info  x temp->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 */ }

17 TANT QUE (x  fin) FAIRE {
Autre méthode . TANT QUE (x  fin) FAIRE { reserver (cour->suiv) /* idem à reserver(temp); cour->suiv  temp; */ cour  cour->suiv cour->info  x cour->suiv  NULL saisir(x) }

18 2. Supprimer un élément de la liste.
On suppose que la liste existe données : T x données modifiées : liste *pp ré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);

19 {variables locales : liste prec, cour ; logique ok
ok  faux SI (*pp->info = x) ALORS { prec  *pp *pp  *pp->suiv ok  vrai liberer(prec) /*suppression du premier élément */ }

20 SINON { prec  *pp cour  *pp->suiv TANT 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  vrai prec->suiv  cour->suiv /* création du lien entre celui qui précède un élément à supprimer et celui qui le suit */ liberer(cour) } prec  cour /* mémorisation de la place d'élément précédent l'élément à tester */ cour  cour->suiv retourner ok

21 3. Insertion d’un élément dans une liste chaînée triée
données T x données modifiées liste *pp Entête en C : void insert (T x, liste *pp);

22 {variables locales : ptr_liste cour, prec ; logique trouve
SI (*pp = NULL) ALORS { reserver(*pp) *pp->info  x *pp->suiv  NULL } SINON SI (x < *pp->info) ALORS reserver(cour) cour->info  x cour->suiv  *pp *pp  cour

23 SINON { trouve  faux prec  *pp cour  *pp->suiv TANT QUE ((cour  NULL) et (trouve = faux)) FAIRE SI (x < cour->info) ALORS trouve  vrai reserver(prec->suiv) prec  prec->suiv prec->info  x prec->suiv  cour } prec  cour cour  cour->suiv

24 SI (cour = NULL) ALORS { reserver (prec->suiv) cour  prec->suiv cour->info  x cour->suiv  NULL }

25 4. Suppression d’un élément d’une liste chaînée triée
données : T x données modifiées : liste *pp résultat de type logique Entête en C : int suppr (T x, liste *pp);

26 {variables locales : ptr_liste cour, prec ; logique trouve
trouve  faux SI (*pp  NULL) ALORS SI (x = *pp->info) ALORS { cour  *pp *pp  *pp->suiv liberer (cour) trouve  vrai }

27 SINON { prec  *pp cour  *pp->suiv TANT QUE ((trouve = faux) et (cour  NULL)) FAIRE SI (x = cour->info) ALORS prec->suiv  cour->suiv liberer (cour) trouve  vrai } SI (x > cour->info) ALORS prec  cour cour  cour->suiv cour  NULL retourner trouve

28 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.

29 Exemple d'utilisation d'une liste chaînée bidirectionnelle
typedef struct doub { T info ; struct doub *suiv, *prec ; } doub ; typedef doub *liste_doub ;

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->suiv TANT QUE (p  NULL) FAIRE afficher (p->info) p  p->prec }


Télécharger ppt "Chap. 1 Structures séquentielles : listes linéaires"

Présentations similaires


Annonces Google