Structures de données IFT-2000 Abder Alikacem Retour sur les listes ordonnées Département dinformatique et de génie logiciel Édition Septembre 2009
Plan Retour au type abstrait liste ordonnée, implantation par: des tableaux dynamiques des listes simplement chaînées des listes doublement chaînées des listes circulaires (anneaux) Retour aux structures de données génériques Retour à la gestion des exceptions
Allocation de mémoire structure simple Un tableau séquentialité des adresses faciles à gérer Les tableaux un inconvénient important. Spécification de sa taille Solution: lallocation dynamique de la mémoire
Un tableau alloué du monceau (tas ou heap) Taille décidé par lutilisateur #include using namespace std; #pragma warning( disable : 4290 ) #define MAX_LISTE 100 template class Liste { public: //… private: int tailleMax; // taille maximum de la liste int cpt; // cardinalité de la liste T * tab; // tableau "dynamique" contenant les éléments de la liste } ; #include "Liste.inl" Liste ordonnée Implantation dans un tableau dynamique
private : int tailleMax; int cpt; T* tab; // implantation dans un tableau dynamique }; Tableau tab réservé dans le tas Constructeur avec un paramètre : taille maximum ==> bonne implantation si on peut évaluer la taille maximum à lutilisation de la pile Liste ordonnée
Gestion du tableau dynamique Il faut donc modifier le constructeur dune liste: allouer un tableau sur le tas et dont le pointeur sera assigné à au membre privé tab. template Liste ::Liste (int max) throw(bad_alloc) { tailleMax=max; cpt = 0; tab = new T [tailleMax]; } Le destructeur de la liste : Libération de lespace du tableau pointé par tab template Liste ::~Liste () // Destructeur { delete [] tab ; cpt = tailleMax = 0; } Constructeur Destructeur
Gestion du tableau dynamique Il ne faut pas oublier le constructeur de copie: allouer un tableau sur le tas et dont le pointeur sera assigné à au membre privé tab puis copier de linstance source template Liste :: Liste(const Liste & source) throw (bad_alloc) : tailleMax(source.tailleMax) { cpt= source.cpt; tab = new T [tailleMax]; for (int position =0; position < source.cpt; ++position) tab[position]= source.tab[position]; } Constructeur de copie
Gestion du tableau dynamique et la surcharge de lopérateur = allouer un tableau sur le tas et dont le pointeur sera assigné à au membre privé tab puis copier de linstance source, ne pas oublier de nettoyer… template Liste & Liste ::operator = (const Liste & l) throw(bad_alloc) { if (tab!=0) delete [] tab; //nettoyer... tab=new T [l.tailleMax]; for (int i=0; i< l.cpt; i++) tab[i]=l.tab[i]; tailleMax=l.tailleMax; cpt=l.cpt; return (*this); } Surcharge de lopérateur =
Les listes ordonnées Une approche traditionnelle par rapport à lusage de tableaux pour implanter une liste est à travers lutilisation des pointeurs. Cette approche fait en sorte que la mémoire est allouée dune manière dynamique dans le sens que les cellules mémoire sont allouées au besoin. Les éléments dune liste seront tout simplement chaînés entre eux. Il existe plusieurs types de listes chaînées dépendant de la manière dont on se déplace dans la liste : 1. les listes chaînées simples, 2. les listes doublement chaînées, 3. les listes circulaires. Implantation par une liste chaînée
Pourquoi les listes chaînées Les tableaux sont un type de données très utile en programmation mais présentent 2 limitations : 1.Les données sont contiguës (les unes derrières les autres) et donc linsertion dun nouvel élément au milieu du tableau demande la recopie (le décalage) de tous les éléments suivants. =) insertion en O(n) 2. Augmenter la taille (par exemple si elle nest pas connue a priori) nécessite la création dun nouveau tableau =) O(n) 3. 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.
Les listes ordonnées Cest la liste de base dont chaque élément appelé noeud contient deux parties : 1. une partie contenant linformation proprement dite 2. et une partie appelée pointeur qui lie le noeud au noeud suivant. Implantation dans une liste chaînée Implantation : Les tableaux Les listes chaînées. Représentation : inclure dans chaque nœud un pointeur sur le nœud qui le suit logiquement (mais pas nécessairement physiquement).
Les listes ordonnées Le noeud étant un objet distinct, il est intéressant de définir une classe pour les nœuds (classe Noeud). La classe Noeud contient deux constructeurs, un qui prend une valeur initiale pour la partie information et lautre non. Elle contient également un destructeur qui ne fait rien de spécial. Il est facile de voir les opération dinsertion et de suppression se font en un temps constant (O(1)) puisquelles consistent essentiellement en des mises à jour de pointeurs. Implantation dans une liste chaînée
Les listes ordonnées Implantation dans une liste chaînée // fichier Noeud.h // déclaration de la classe Noeud #ifndef NOEUD_H #define NOEUD_H class Noeud; typedef Noeud * elem; template class Noeud{ //Un noeud typique de la liste public: T el;//L'élément de base de la liste elem suivant;//Un pointeur vers le noeud suivant Noeud (const T& data_item, elem next_ptr = 0) : el(data_item), suivant(next_ptr) {} ~Nœud(){}; }; #endif el suivant
Les listes ordonnées Implantation dans une liste chaînée #ifndef LISTE_H #define LISTE_H #include "Noeud.h" #pragma warning( disable : 4290 ) template class Liste { public: Liste(){debut = 0;} // constructeur ~Liste(); // destructeur void ajouter(T x, int pos) throw(); int taille() const; bool appartient(T x,) const; friend ostream& operator << (ostream&, const Liste& ); private: elem debut; // Pointeur vers le dernier noeud de la liste } ; #endif
Implantation dans une liste chaînée Une meilleure version: utilisation dune classe interne //… template class Liste { public: //Constructeurs Liste(){debut = 0;}// constructeur Liste(const Liste&) throw(bad_alloc);// constructeur de copie ~Liste();// destructeur //Surcharge d'opérateurs Liste & operator = (const Liste &) throw (bad_alloc); private: class Noeud{//Un noeud typique de la liste public: T el;//L'élément de base de la liste Noeud * suivant; //Un pointeur vers le noeud suivant Noeud (const T& data_item, Noeud * next_ptr = 0) : el(data_item), suivant(next_ptr) {} }; typedef Noeud * elem; elem debut; //Pointeur vers le premier noeud de la liste } ;
Implantation dans une liste chaînée template Liste :: ~Liste() {elem courant = debut; while(courant!=0) { debut=debut->suivant; delete courant; courant=debut; } ~Liste() // destructeur Destructeur
Implantation dans une liste chaînée template int Liste :: taille() const { elem ptr; //Pour parcourir la liste int compte(0); //Pour compter les pointeurs non nuls ptr = debut; while (ptr != 0) { compte++; ptr = ptr->suivant; } return compte; } taille() // taille de la liste
Implantation dans une liste chaînée template bool Liste :: appartient(T& x) const { elem courant = debut; while (courant!=0) { if (courant->el == x) return true; courant = courant->suivant; } return false; } appartient() // recherche
Implantation dans une liste chaînée template void Liste :: ajouter(T x, int pos) throw(range_error, bad_alloc) { elem courant;//pointeur de service pour se promener dans la liste elem nouveau;//pour l'adresse de la nouvelle structure pour entreposer x int cpt=1;//compteur de boucle //Vérification des hypothèses (préconditions) //La position if(pos taille() +1) throw range_error("Position d'ajout erronée"); //La mémoire nouveau = new Noeud(x); //on appelle le constructeur de la classe Noeud nouveau->suivant = 0; //suite prochaine diapositive ajouter() // lajout délément
Implantation dans une liste chaînée //Cas où l'ajout se fait en première position if(pos==1) { nouveau->suivant=debut; debut = nouveau; return ; } //Ajout dans une autre quelconque position courant = debut;//on se positionne au début de la liste chaînée while (cpt< pos - 1) { courant=courant->suivant;//on passe à la structure suivante.. cpt++;//...et on compte } //A: courant pointe la structure d'avant le nouvel ajout nouveau->suivant = courant->suivant; //on chaîne la nouvelle structure … courant->suivant = nouveau;//on chaîne la structure qui doit précéder … } ajouter() // lajout délément
Implantation dans une liste chaînée template void Liste :: enleverEl(T x) throw(logic_error) { elem trouve = debut; elem pred; //on prend pour acquis que l'opérateur != s'applique sur x, le mieux est … while (trouve != 0 && trouve->el != x ) { pred = trouve; // pour marquer le noeud prédécesseur à celui qui contient x trouve = trouve->suivant; } if (trouve== 0) throw logic_error("EnleverEl: x n'est pas dans la liste"); else { //suite prochaine diapositive enleverEl() // enlever la première occurrence dun élément
Implantation dans une liste chaînée else { if (debut == trouve) { / x est au début de la liste debut = debut->suivant; } else { //..il est ailleur pred->suivant = trouve->suivant; } // on "coupe" la structure supprimée de la liste trouve->suivant = 0; //libération de la mémoire associée à la structure supprimée delete trouve; } enleverEl() // enlever la première occurrence dun élément
Implantation dans une liste chaînée template Liste & Liste ::operator = (const Liste & source)throw(bad_alloc) { //nettoyage... if (debut!=0) {elem temp= debut; while (debut !=0) { debut = temp->suivant; delete temp; temp = debut; } //suite prochaine diapositive Operator = () // surcharge de lop. daffectation
Implantation dans une liste chaînée if (source.debut== 0) debut = 0; // la liste originale est vide else { //la copie try{ //copie le permier noeud debut = new Noeud(source.debut->el); debut->suivant = 0; // copie le reste de la liste elem nouveau = debut; for(elem temp = source.debut->suivant; temp != 0;temp = temp->suivant) { nouveau->suivant = new Noeud(temp->el); nouveau = nouveau->suivant; nouveau->suivant = 0; } nouveau->suivant = 0; }catch(exception&){ //suite dans la prochaine diapositive Operator = () // surcharge de lop. daffectation
Implantation dans une liste chaînée catch(exception&){ //suite dans la prochaine diapositive //Si on arrive ici c'est qu'il y a une erreur d'allocation //On doit donc libérer la mémoire déjà allouée elem temp= debut; while (temp!=0) { debut = temp->suivant; delete temp; temp = debut; } //On relance alors l'exception pour indiquer qu'une erreur est survenue throw; } return (*this); } Operator = () // surcharge de lop. daffectation
Implantation dans une liste chaînée template class Liste { public: //.. friend ostream& operator << (ostream& f, const Liste& l){ elem courant=l.debut; while(courant!=0) { f el << " "; courant=courant->suivant; } return f; } private: //.. } ; Operator << () // surcharge de lop. <<
Dans les situations où il est souvent nécessaire datteindre des éléments d'une chaîne qui se trouvent quelques positions avant un élément donné, on peut alors adjoindre, à chaque élément, un pointeur supplémentaire vers son prédécesseur. SommetGSommetD … Implantation dans une liste doublement chaînée Nœud typique dune liste chaînée : Nœud typique dune liste doublement chaînée : Info LienPtrG Info PtrD
Implantation dans une liste doublement chaînée template class Liste { public: //.. private: class Noeud{//Un noeud typique de la liste public: T el;//L'élément de base de la liste Noeud * suivant;//Un pointeur vers le noeud suivant Noeud * precedent;//Un pointeur vers le noeud précédent Noeud (const T& data_item, Noeud * next_ptr = 0, Noeud * pred_ptr =0) : el(data_item), suivant(next_ptr), precedent(pred_ptr){} }; typedef Noeud * elem; elem sommetG;//Pointeur vers le sommet à gauche elem sommetD;//...vers le sommet droit int cpt;//cardinalité de la liste } ;
Les listes Remarque La liste doublement chaînée peut être implantée de la même façon que la liste simplement chaînée. La partie publique reste inchangée. Cependant, les fonctions dinsertion, suppression et les différents constructeurs sont à redéfinir. Les autres fonctions sur les listes chaînées simples peuvent être utilisées sans changement dans le cadre des listes doublement chaînées.
Liste doublement chaînée Exemple dune gestion des 2 pointeurs de chaînage SG = new …SG= sommetG SG precedent = 0SD= sommetD SG item = info SD = SG et Demander info Tant que info sentinelle debut SD suivant = new … SD suivant precedent = SD SD = SD suivant SD item = info Demander info fin SD suivant = 0
Liste doublement chaînée Ajouter un élément Ajouter N avant P : …… P N
Ajouter un élément Ajouter N avant P : P precedent suivant = N N precedent = P precedent N suivant = P P precedent = N …… P N Liste doublement chaînée
Ajouter un élément Ajouter N avant P : P precedent suivant = N N precedent = P precedent N suivant = P P precedent = N … … P N Liste doublement chaînée
Ajouter un élément Ajouter N avant P : P precedent suivant = N N precedent = P precedent N suivant = P P precedent = N …… P N Liste doublement chaînée
Ajouter un élément Ajouter N avant P : P precedent suivant = N N precedent = P precedent N suivant = P P precedent = N …… P N Liste doublement chaînée
Ajouter un élément Ajouter N avant P : P precedent suivant = N N precedent = P precedent N suivant = P P precedent = N …… P N Liste doublement chaînée
Ajouter un élément Ajouter N avant P : P precedent suivant = N N precedent = P precedent N suivant = P P precedent = N …… P N Liste doublement chaînée
Ajouter un élément Ajouter N après P : …… P N Liste doublement chaînée
Ajouter un élément Ajouter N après P : N suivant = P suivant P suivant precedent = N P suivant = N N precedent = P …… P N Liste doublement chaînée
Ajouter un élément Ajouter N après P : N suivant = P suivant P suivant precedent = N P suivant = N N precedent = P …… P N Liste doublement chaînée
Ajouter un élément Ajouter N après P : N suivant = P suivant P suivant precedent = N P suivant = N N precedent = P …… P N Liste doublement chaînée
Ajouter un élément Ajouter N après P : N suivant = P suivant P suivant precedent = N P suivant = N N precedent = P …… P N Liste doublement chaînée
Ajouter un élément Ajouter N après P : N suivant = P suivant P suivant precedent = N P suivant = N N precedent = P …… P N Liste doublement chaînée
Ajouter un élément Ajouter N après P : N suivant = P suivant P suivant precedent = N P suivant = N N precedent = P …… P N Liste doublement chaînée
Ajouter un élément Ajouter N après le sommet droit : … P N … Liste doublement chaînée
Ajouter un élément Ajouter N après le sommet droit : sommetD suivant = N N precedent = sommetD sommetD = N N suivant = 0 … P N … Liste doublement chaînée
Ajouter un élément Ajouter N après le sommet droit : sommetD suivant = N N precedent = sommetD sommetD = N N suivant = 0 … P N … Liste doublement chaînée
Ajouter un élément Ajouter N après le sommet droit : sommetD suivant = N N precedent = sommetD sommetD = N N suivant = 0 … P N … Liste doublement chaînée
Ajouter un élément Ajouter N après le sommet droit : sommetD suivant = N N precedent = sommetD sommetD = N N suivant = 0 … P N … Liste doublement chaînée
Ajouter un élément Ajouter N après le sommet droit : sommetD suivant = N N precedent = sommetD sommetD = N N suivant = 0 … P N … Liste doublement chaînée
Ajouter un élément Ajouter N après le sommet droit : sommetD suivant = N N precedent = sommetD sommetD = N N suivant = 0 … P N … Liste doublement chaînée
Ajouter un élément Ajouter N avant le sommet gauche : … P N … Liste doublement chaînée
Ajouter un élément Ajouter N avant le sommet gauche : N suivant = sommetG sommetG precedent = N sommetG = N N precedent = 0 … P N … Liste doublement chaînée
Ajouter un élément Ajouter N avant le sommet gauche : N suivant = sommetG sommetG precedent = N sommetG = N N precedent = 0 … P N … Liste doublement chaînée
Ajouter un élément Ajouter N avant le sommet gauche : N suivant = sommetG sommetG precedent = N sommetG = N N precedent = 0 … P N … Liste doublement chaînée
Ajouter un élément Ajouter N avant le sommet gauche : N suivant = sommetG sommetG precedent = N sommetG = N N precedent = 0 … P N … Liste doublement chaînée
Ajouter un élément Ajouter N avant le sommet gauche : N suivant = sommetG sommetG precedent = N sommetG = N N precedent = 0 … P N … Liste doublement chaînée
Ajouter un élément Ajouter N avant le sommet gauche : N suivant = sommetG sommetG precedent = N sommetG = N N precedent = 0 … P N … Liste doublement chaînée
Supprimer un élément Supprimer le nœud avant P …… P Liste doublement chaînée
Supprimer un élément Supprimer le nœud avant P N = P precedent P precedent = P precedent precedent P precedent suivant = P N suivant = 0 N precedent = 0 delete N N = 0 …… P N Liste doublement chaînée
Supprimer un élément Supprimer le nœud avant P N = P precedent P precedent = P precedent precedent P precedent suivant = P N suivant = 0 N precedent = 0 delete N N = 0 …… P N Liste doublement chaînée
Supprimer un élément Supprimer le nœud avant P N = P precedent P precedent = P precedent precedent P precedent suivant = P N suivant = 0 N precedent = 0 delete N N = 0 …… P N Liste doublement chaînée
Supprimer un élément Supprimer le nœud avant P N = P precedent P precedent = P precedent precedent P precedent suivant = P N suivant = 0 N precedent = 0 delete N N = 0 …… P N Liste doublement chaînée
Supprimer un élément Supprimer le nœud avant P N = P precedent P precedent = P precedent precedent P precedent suivant = P N suivant = 0 N precedent = 0 delete N N = 0 …… P N Liste doublement chaînée
Supprimer un élément Supprimer le nœud avant P N = P precedent P precedent = P precedent precedent P precedent suivant = P N suivant = 0 N precedent = 0 delete N N = 0 …… P N Liste doublement chaînée
Supprimer un élément Supprimer le nœud après P …… P Liste doublement chaînée
Supprimer un élément Supprimer le nœud après P N = P suivant P suivant = P suivant suivant P suivant precedent = P N suivant =0 N precedent = 0 delete N N = 0 …… P N Liste doublement chaînée
Supprimer un élément Supprimer le nœud après P N = P suivant P suivant = P suivant suivant P suivant precedent = P N suivant = 0 N precedent = 0 delete N N = 0 …… N P Liste doublement chaînée
Supprimer un élément Supprimer le nœud après P N = P suivant P suivant = P suivant suivant P suivant precedent = P N suivant = 0 N precedent = 0 delete N N = 0 …… N P Liste doublement chaînée
Supprimer un élément Supprimer le nœud après P N = P suivant P suivant = P suivant suivant P suivant precedent = P N suivant = 0 N precedent = 0 delete N N = 0 …… N P Liste doublement chaînée
Supprimer un élément Supprimer le nœud avant P N = P precedent P precedent = P precedent precedent P precedent suivant = P N suivant = 0 N precedent = 0 delete N N = 0 …… N P Liste doublement chaînée
Supprimer un élément Supprimer le nœud avant P N = P precedent P precedent = P precedent precedent P precedent suivant = P N suivant = 0 N precedent = 0 delete N N = 0 …… N P Liste doublement chaînée
Supprimer un élément Supprimer le nœud P …… P Liste doublement chaînée
Supprimer un élément Supprimer le nœud P P precedent suivant = P suivant P suivant precedent = P precedent P precedent = 0 P suivant = 0 delete P …… P Liste doublement chaînée
Supprimer un élément Supprimer le nœud P P precedent suivant = P suivant P suivant precedent = P precedent P precedent = 0 P suivant = 0 delete P …… P Liste doublement chaînée
Supprimer un élément Supprimer le nœud P P precedent suivant = P suivant P suivant precedent = P precedent P precedent = 0 P suivant = 0 delete P …… P Liste doublement chaînée
Supprimer un élément Supprimer le nœud P P precedent suivant = P suivant P suivant precedent = P precedent P precedent = 0 P suivant = 0 delete P …… P Liste doublement chaînée
Supprimer un élément Supprimer le nœud P P precedent suivant = P suivant P suivant precedent = P precedent P precedent = 0 P suivant = 0 delete P …… P Liste doublement chaînée
Supprimer un élément Supprimer le sommet gauche … N … Liste doublement chaînée
Supprimer un élément Supprimer le sommet gauche N = sommetG sommetG = sommetG suivant sommetG precedent = 0 N suivant = 0 delete N N = 0 … N … Liste doublement chaînée
Supprimer un élément Supprimer le sommet gauche N = sommetG sommetG = sommetG suivant sommetG precedent = 0 N suivant = 0 delete N N = 0 … N … Liste doublement chaînée
Supprimer un élément Supprimer le sommet gauche N = sommetG sommetG = sommetG suivant sommetG precedent = 0 N suivant = 0 delete N N = 0 … N … Liste doublement chaînée
Supprimer un élément Supprimer le sommet gauche N = sommetG sommetG = sommetG suivant sommetG precedent = 0 N suivant = 0 delete N N = 0 … N … Liste doublement chaînée
Supprimer un élément Supprimer le sommet gauche N = sommetG sommetG = sommetG suivant sommetG precedent = 0 N suivant = 0 delete N N = 0 … N … Liste doublement chaînée
Supprimer un élément Supprimer le sommet gauche N = sommetG sommetG = sommetG suivant sommetG precedent = 0 N suivant = 0 delete N N = 0 … N … Liste doublement chaînée
Supprimer un élément Supprimer le sommet droit Le même algorithme que pour supprimer le sommet gauche, mais en échangeant les rôles des pointeurs precedent et suivant et en remplaçant sommetG par sommetD. Liste doublement chaînée
Implantation dans une liste circulaire (anneau) Une liste où le pointeur NULL du membre suivant dernier élément est remplacé par ladresse du premier élément est appelée liste circulaire. Dans une liste circulaire tous les noeuds sont accessibles à partir de nimporte quel autre noeud. Une liste circulaire na pas de premier et de dernier noeud. 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. Une liste circulaire peut être simplement chaînée ou doublement chaînée. Notez que la concaténation de deux listes circulaires peut se faire sans avoir à parcourir les deux listes. Implantation par une liste circulaire
Les listes chaînées circulaires permettent de rendre lécriture de certains algorithmes dune manière plus efficace. sommet... Implantation dans une liste circulaire (anneau) Cependant, il est plus intéressant davoir un pointeur dernier au lieu dun pointeur sommet dernier...
Manipulations : Linsertion, la suppression et le défilement des anneaux sont très similaires à ceux que nous avons vus pour les chaînes linéaires. Il ne faut pas oublier de mettre correctement à jour le pointeur dernier dans les opérations d'insertion ou de suppression en fin danneau. Lors dune insertion après un élément donné, il faut tester si l'insertion s'est faite en "fin d'anneau" pour ajuster le pointeur dernier. Listes circulaires (les anneaux) Caractéristiques : Un article particulier est accessible depuis un article quelconque. La chaîne n'a ni début ni fin. Le premier élément est égal au pointeur dernier >lien. L'emploi d'une liste circulaire présente cependant un inconvénient majeur : il faut faire attention de ne pas créer des boucles infinies. Ces boucles sont possibles si l'on néglige la détection correcte de la fin de parcours. Une façon de faire consiste à associer l'existence de toute liste circulaire avec la présence obligatoire d'un article spécial appelé tête de liste ou élément de tête.
Listes circulaires (les anneaux) template class Liste { public: //... friend ostream& operator << (ostream& f, const Liste& l){ if(l.dernier == 0) return f; elem courant = l.dernier->suivant; while(courant!=l.dernier){ f el suivant; } f el; return f; } private: class Noeud{ public: T el; Noeud * suivant; Noeud (const T& data_item, Noeud * next_ptr = 0) : el(data_item), suivant(next_ptr) {} }; typedef Noeud * elem; elem dernier;/*Pointeur vers le dernier noeud de la liste*/ } ;
Anneau bidirectionnel Sommet … Listes circulaires (les anneaux )
Limplantation de la liste par tableau impose le choix dune taille maximum de la liste. Beaucoup despace risque dêtre inutilisé. Dans le cas de limplantation par liste chaînée, lespace est alloué uniquement aux éléments qui appartiennent effectivement à la liste. Dans le cas de limplantation par tableau aucune mémoire supplémentaire nest nécessaire pour stocker un élément de la liste. Dans le cas de liste chaînée, un espace pour le pointeur est ajouté pour chaque élément de la liste. Laccès à un élément par sa position est plus rapide dans le cas de limplantation par tableau, il se fait en un temps constant (O(1)). Dans le cas de la liste chaînée, nous devons parcourir la liste du début jusquà la position désirée (O(n)). Les insertions et les suppressions déléments sont plus coûteuses dans le cas dans l implantation par tableau car elles nécessitent des déplacements déléments. Comparaison des implantations de la liste
Liste avec tableau: 1. Insertion et suppression sont O(n). 2. Précédent et accès direct sont O(1). 3. Tout lespace est alloué à lavance. 4. Pas despace autre que les valeurs. Liste dans une liste chaînée: 1. Insertion et suppression sont O(1). 2. Précédent et accès direct sont O(n). 3. Lespace augmente avec la liste. 4. Chaque élément requiert de lespace pour les pointeurs Comparaison des implantations de la liste
Ce que jai appris aujourdhui! Les bases de la formalisation des données : les structures de données abstraites La structures de données abstraites la plus utilisée en informatique (en plus des tableaux et des types élémentaires) : les listes. A pouvoir faire des modèles génériques de traitements ou de classes, indépendamment du type, ce que lon appelle de la programmation générique. Comment déclarer de tels modèles Comment en créer des instances Comment spécialiser certains modèles