Télécharger la présentation
La présentation est en train de télécharger. S'il vous plaît, attendez
Publié parÉloy Blanchet Modifié depuis plus de 10 années
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 ((pNULL) 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->infox 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 }
Présentations similaires
© 2024 SlidePlayer.fr Inc.
All rights reserved.