Télécharger la présentation
La présentation est en train de télécharger. S'il vous plaît, attendez
Publié parRoch Rougier Modifié depuis plus de 10 années
1
IFT-2000: Structures de Données Listes chaînées Dominic Genest, 2009
2
Les désavantages des tableaux dynamiques Les éléments risquent dêtre déplacés dans un tout nouvel espace-mémoire à chaque ajout ou suppression. Ce qui fait que les itérateurs (pointeurs) à ces éléments nont aucune garantie de demeurer valides à partir du moment où on ajoute ou supprime. Insérer dans un tableau à une position quelconque (ni au début ni à la fin) implique un décalage dune partie des éléments, ce qui peut être coûteux. Les éléments doivent être placés de façon contigüe (dans un seul gros bloc) en mémoire, ce qui fait quon ne peut pas « remplir les trous » en mémoire. Dominic Genest, 2009
3
Listes chaînées C typedef struct nœud { Etudiant etudiant; struct nœud *suivant; } Noeud; typedef struct { Nœud *premier; } Universite; CodeErreur initUniversite(Universite *u); void detruitUniversite(Universite *u); CodeErreur ajoutUniversite(Universite *u, Etudiant et); int age_selon_nom(const Universite *u, char const *nom); C++ typedef struct { Universite(); ~Universite(); void ajout(Etudiant et); int age_selon_nom(char const *nom) const; private: struct Nœud // Struct interne { Etudiant etudiant; Nœud *suivant; }; Nœud *premier; } Universite; Dominic Genest, 2009
4
Listes chaînées Le champ « premier » contient ladresse-mémoire du nœud correspondant au premier élément de la liste. Cest son point dentrée. Le champ « suivant » de chaque nœud contient ladresse- mémoire du nœud suivant de la liste. Le champ « suivant » du dernier nœud de la liste contient zéro. Cela marque la fin de la liste et cest la plupart du temps ce qui sera vérifié dans la condition darrêt des boucles qui seront faites sur les listes chaînées. Quand le champ « premier » vaut zéro, cela signifie que la liste est vide. Parfois, dans certaines implémentations (cest le cas souvent dans la STL), un nœud supplémentaire artificiel est toujours ajouté au début de la liste afin doptimiser certains traitements. On appelle ce nœud « nœud factice » et toutes les fonctions doivent considérer quil ne fait pas partie de la liste pour vrai. Dominic Genest, 2009
5
Listes chaînées CodeErreur initUniversite(Universite *u) { u->premier=0; return Ok; } CodeErreur ajoutUniversite(Universite *u, Etudiant et) { // Disons quon ajoute au début Nœud *nouveau_noeud = malloc(sizeof(Nœud)); if(!nouveau_noeud) return Erreur; nouveau_noeud->etudiant = et; nouveau_noeud->suivant = u- >premier; u->premier = nouveau_noeud; return OK; } void detruitUniversite(Universite *u) { Nœud *i = u->premier; while(i) // Équivalent à while(i!=0) { Nœud *a_supprimer = i; i=i->suivant; free(a_supprimer); } Dominic Genest, 2009
6
Organisation en mémoire dune liste chaînée Nœud *nouveau_noeud = malloc(sizeof(Nœud)); if(!nouveau_noeud) return Erreur; nouveau_noeud->etudiant = et; nouveau_noeud->suivant = u->premier; u->premier = nouveau_noeud; Dominic Genest, 2009 3640 suivantetudiant Noeud Dominic, 31, 02700 3640 suivantetudiant Noeud Dominic, 31, 01238 2700 suivantetudiant Noeud Dominic, 31, 00 1238 premier Universite
7
Représentation des pointeurs par des flèches Pour alléger laspect visuel de tels schémas, on peut remplacer les nombres par des flèches dont la pointe indique ladresse-mémoire en question. Le départ de la flèche est à lintérieur du rectangle représentant le pointeur. On représentera la valeur zéro par une ligne diagonale. Par contre, il ne faut pas que cela porte à croire quun quelconque lien spécial entre le pointeur et lendroit pointé est considéré par les ordinateurs. La réalité, cest que le contenu dun pointeur demeure un simple nombre. Dominic Genest, 2009 suivantetudiant Noeud Dominic, 31, 0 3640 suivantetudiant Noeud Dominic, 31, 0 2700 suivantetudiant Noeud Dominic, 31, 0 1238 premier Universite
8
Ajout dans une liste chaînée Nœud *nouveau_noeud = malloc(sizeof(Nœud)); if(!nouveau_noeud) return Erreur; nouveau_noeud->etudiant = et; nouveau_noeud->suivant = u->premier; u->premier = nouveau_noeud; Dominic Genest, 2009 suivantetudiant Noeud Dominic, 31, 0 3640 suivantetudiant Noeud Dominic, 31, 0 2700 suivantetudiant Noeud Dominic, 31, 0 1238 premier Universite suivantetudiant Noeud Dominic, 31, 0 1300
9
Listes chaînées int age_selon_nom(const Universite *u, const char *nom) { Nœud *i; for(i=u->premier;i && strcmp(nom,i- >etudiant.nom)!=0; i=i->suivant); // « ; »: Boucle vide! return i ? i->etudiant.age : -1; } Dominic Genest, 2009
10
Listes doublement chaînées Les listes doublement chaînées sont construites de la même façon, mais chaque nœud possède aussi un autre champ qui contient ladresse-mémoire du nœud précédent. Dominic Genest, 2009 suivantetudiant Noeud Dominic, 31, 0 3640 suivantetudiant Noeud Dominic, 31, 0 2700 suivantetudiant Noeud Dominic, 31, 0 1238 premier Universite precedent dernier
11
Listes doublement chaînées Pour le point dentrée dune liste simplement chaînée, nous avions une structure qui contenait ladresse-mémoire du premier nœud. Avec une liste doublement chaînée, ce nest plus nécessaire. Le point dentrée peut être ladresse- mémoire de nimporte quel nœud de la liste. Parfois, on optera quand même pour deux points dentrée, soit les adresses-mémoire du premier nœud et du dernier noeud. Dominic Genest, 2009
12
Les listes doublement chaînées Dans une liste simplement chaînée, si nous voulions insérer un nœud à une position arbitraire, nous devions obligatoirement avoir ladresse-mémoire du nœud précédent. Dans une liste doublement chaînée, on peut aussi le faire à partir de ladresse-mémoire du nœud suivant. Nous pouvons aussi supprimer un nœud à partir de son adresse seule. Dominic Genest, 2009
13
Suppression dun nœud dune liste doublement chaînée typedef struct nœud { Etudiant et; struct nœud *suiv,*prec; } Nœud; typedef struct { Nœud *premier,*dernier; } Universite; void supprimer(Universite *u, Nœud *n); Dominic Genest, 2009
14
Suppression dun nœud dune liste doublement chaînée void supprimer(Universite *u, Nœud *n) { if(n->prec) n->prec->suiv = n->suiv; if(n->suiv) n->suiv->prec = n->prec; if(u->premier==n) u->premier=n->suiv; if(u->dernier==n) u->dernier=n->prec; free(n); } Dominic Genest, 2009 suivantetudiant Noeud Dominic, 31, 0 3640 suivantetudiant Noeud Dominic, 31, 0 2700 suivantetudiant Noeud Dominic, 31, 0 1238 premier Universite precedent dernier precedent n
15
Listes circulaires Dans une liste circulaire, plutôt que davoir 0 comme valeur dans le champ « suivant » du dernier nœud, on a ladresse-mémoire du premier nœud. Et dans une liste circulaire doublement chaînée, plutôt que davoir 0 comme valeur dans le champ « précédent » du premier nœud, on a ladresse- mémoire du dernier nœud. Dans ce cas, il faut faire attention, lors des itérations pour les recherches, de ne pas boucler à linfini. Il faut mémoriser ladresse-mémoire du nœud où on a commencé litération, et sorganiser pour interrompre litération dès quon y revient. Dominic Genest, 2009
16
Listes chaînées versus tableaux Tableaux (dynamiques ou statiques) Laccès à un élément selon son index (numéro) est instantané Linsertion ou la suppression au début ou à la fin peut se faire de façon instantanée. Linsertion ou la suppression à une position quelconque nécessite un décalage. Les pointeurs vers des éléments peuvent devenir invalides après une suppression dun autre élément, ou un ajout. Les éléments sont tous dans le même bloc en mémoire, ce qui peut aider à optimiser les accès mémoire. Listes chaînées Laccès à un élément selon son index (numéro) nécessite une itération Linsertion ou la suppression au début ou à la fin peut se faire de façon instantanée. Linsertion ou la suppression à une position quelconque peut se faire de façon instantanée (pourvu quon ait déjà trouvé le point où un veut faire lopération). Les pointeurs vers des éléments restent toujours valides même après une suppression dun autre élément, ou un ajout. Les éléments peuvent être dispersés en mémoire, donc les manipulation de mémoire peuvent être plus coûteux. Dominic Genest, 2009
Présentations similaires
© 2024 SlidePlayer.fr Inc.
All rights reserved.