Département Informatique
Structures de données – partie 1 tableaux, listes chaînées piles, files d'attente
Programmation objet
Cours n°5
Département Informatique
Département Informatique Tableaux
Une structure de données de type tableau présente les caractéristiques :
• Espace contigu de mémoire
• Accès via un indice
• Structure compacte et non fragmentée
• Allocation rapide
• Réallocation lente
• Insertion très lente
• Suppression lente
• Accès aléatoire donc rapide
• Copie des éléments (sémantique de valeur)
• Type homogène des éléments
• Occupation mémoire n*sizeof(elt)
Département Informatique
On peut utiliser une implémentation simple, composée de :
• L'adresse (pointeur) du premier élément
• Le nombre d'éléments
Cette implémentation ne dépend pas du type d'éléments stockés dans le tableau : nous pouvons donc utiliser un modèle.
template <class elt> class tableau { elt* p_elements;
int n_elements;
};
Département Informatique
Département Informatique Actions courantes sur un tableau de taille n
Ajout d'éléments (fin du tableau)
Si l'espace mémoire le permet, opération simple O(1), sinon voir ci-après Ajout d'éléments (milieu du tableau)
Allocation d'un 2e tableau, recopie des éléments : n opérations Suppression d'éléments
Copies d'éléments pour « boucher » les trous : n opérations Recherche par la valeur
Parcours depuis le début. N opérations
Département Informatique Implémentation C++ du tableau std::vector<T>
Il existe en C (donc en C++) un semblant de tableau mais qui ne remplit pas exactement le rôle de tableau (mauvaise sémantique).
On utilisera donc systématiquement std::vector en C++ pour représenter un tableau.
Opérations courantes :
• operator[]
• size(), resize()
• std::find()
• reserve()
L'accès se fait soit par indice soit par itérateur.
Département Informatique
Département Informatique Liste chaînée
Principe : chaque élément est lié au suivant dans une structure non contiguë en mémoire.
• Espace fragmenté de mémoire
• Structure non compacte
• Allocation rapide
• Réallocation rapide
• Insertion rapide
• Suppression rapide
• Accès séquentiel
• Copie des éléments (sémantique de valeur)
• Type non homogène des éléments possible
• Occupation mémoire n*(sizeof(elt)+sizeof(elt*))
• Parcours à double sens possible
Département Informatique
Chaque élément à stocker est donc encapsulé dans un objet contenant en outre un pointeur sur l'élément suivant.
Département Informatique
Département Informatique Opérations standard sur la liste
Ajout d'éléments aux extrémités Allocation, affectation de pointeurs.
Suppression d'éléments
Affectation de pointeurs, libération mémoire Recherche par la valeur
Parcours depuis le début. N opérations Insertion d'élément
Recherche de la position puis idem ajout. N opérations.
Département Informatique
Département Informatique Exemple d'implémentation en C++
template <class elt> class list {
struct elt_list { elt valeur;
elt_list* suivant;
};elt_list* premier;
};
Département Informatique
Département Informatique Implémentations C++
std::list est une implémentation standard de liste chaînée Opérations courantes :
• push_back / push_front
• pop_back / pop_front
• insert
• erase
• size()
• std::find()
L'accès se fait au moyen de la classe interne iterator.
La classe std::deque fournit une liste chaînée modifiée pour utiliser également un opérateur [] (attention : la structure est celle d'une liste)
Département Informatique
Département Informatique Exemples d'utilisation de std::list
std::list< std::string> ListeChaines;
ListeChaines.push_back("steve");
ListeChaines.push_back("nicko");
ListeChaines.push_back("Adrian");
ListeChaines.push_front("Bruce");
ListeChaines.push_back("Dave");
Affiche(ListeChaines);
std::list<std::string>::iterator i1 =
std::find(ListeChaines.begin(),ListeChaines.end(),"Adrian" );
i1 = ListeChaines.insert(i1, "jannis");
Affiche(ListeChaines);
ListeChaines.erase(i1);
template<class iterator>
void Affiche(iterator a,iterator b) {
for(iterator i=a;i!=b;++i) std::cout<< *i<<' ';
}
Département Informatique
Département Informatique Structures de données abstraites
A partir de ces structures de données mémoires (physiques) appelées séquences ou conteneurs élémentaires, on peut construire des
structures de données logiques.
Ces structures de données représentent non pas la manière d'implanter les données en mémoire, mais le comportement nécessaire à
l'application.
Les structures les plus simples sont la pile et la file d'attente.
Département Informatique
Département Informatique Pile : principes
Une pile représente un ensemble de données où l'on ne peut accéder qu'au dernier élément entré, qui devient donc le premier à sortir.
On les appelle parfois LIFO (last in first out)
L'accès n'étant qu'à un seul sens, la pile peut avoir une taille fixe ou variable sans difficultés.
On peut donc la baser sur un tableau (plus compact). Néanmoins, une liste chaînée peut faire l'affaire.
Département Informatique
Département Informatique Exemple d'implémentation d'une pile
template <class elt> class pile { std::vector<elt> elements;
public:
void push(const elt& e){elements.push_back(e);}
void pop(){elements.pop_back();}
elt& top() {return elements.back();}
const elt& top() const {return elements.back();}
bool empty() const {return elements.size()==0;}
};
Implémentation standard C++ : std::stack<>
Département Informatique File d'attente : principes
Une file représente un ensemble de données avec accès en lecture à une extrémité et accès en écriture à l'autre extrémité.
On a donc le premier élément entré qui sera le premier élément sorti.
On parle pour une file de FIFO (first in first out)
La file peut être de taille fixe , circulaire ou de taille variable...
Département Informatique
Département Informatique Exemple d'implémentation d'une file simple en C++
template <class T> class file { std::list<T> elements;
public:
void push(const T& elt){elements.push_front();}
void pop(){elements.pop_back();}
T& top(){return elements.back();}
const T& top() const {return elements.back();}
bool empty() const {return elements.empty();}
};
Implémentation standard C++ : std::queue<>
Département Informatique
Département Informatique Autres structures standard
En C++ il existe une autre file d'attente : la file d'attente à priorité Dans cette collection, l'élément qui sort en premier est le plus prioritaire.
On associe donc une notion de priorité à chaque élément (par défaut ils sont classés par ordre croissant, le plus prioritaire est le plus petit).
std::priority_queue<std::string> file;
file.push("klaus");
file.push("rudolf");
file.push("mattias");
std::cout<<file.top()<<std::endl;
file.pop();
std::cout<< file.top() << std::endl;
Département Informatique Département Informatique
Prochain cours :
Structures de données – partie 2 conteneurs évolués C++
algorithmes génériques
A la semaine prochaine !