Fiche récapitulative générée pour impression / export PDF.
Licence 3 · Informatique L3 — Algorithmique, structures de données et graphes
Structures de données : piles, files, arbres et tas
Structures de données : piles, files, arbres et tas
1. Piles (LIFO) et files (FIFO)
Une pile (stack) est une structure « dernier entré, premier sorti » (LIFO) : les deux opérations de base sont empiler (push, ajouter au sommet) et dépiler (pop, retirer le sommet), chacune en .
empiler(P, x) : ajouter x au sommet de P
dépiler(P) : retirer et renvoyer l'élément au sommet de P
Une file (queue) est « premier entré, premier sorti » (FIFO) : enfiler (enqueue, ajouter à l'arrière) et défiler (dequeue, retirer à l'avant), chacune en avec une implémentation adaptée (liste doublement chaînée ou tableau circulaire).
Applications classiques : une pile sert à l'évaluation d'expressions arithmétiques (notation polonaise inversée), à la gestion des appels de fonctions récursives, au parcours en profondeur (DFS) d'un graphe. Une file sert au parcours en largeur (BFS), à l'ordonnancement de tâches (FIFO).
2. Arbres binaires
Un arbre binaire est une structure récursive : chaque nœud a au plus deux enfants (gauche, droit). La hauteur d'un arbre à nœuds vérifie (borne atteinte par un arbre parfaitement équilibré) et (cas dégénéré, arbre filiforme).
Arbre binaire de recherche (ABR) : pour chaque nœud, toutes les valeurs du sous-arbre gauche sont inférieures, toutes celles du sous-arbre droit sont supérieures. Recherche, insertion, suppression sont en — donc si l'arbre est équilibré, mais dans le pire cas (arbre filiforme, par exemple après insertions dans un ordre déjà trié).
3. Arbres équilibrés
Les arbres AVL et arbres rouge-noir garantissent en maintenant un équilibre lors des insertions/suppressions (rotations locales en par niveau). Cela garantit que les opérations de base restent en dans le pire cas, contrairement à l'ABR naïf.
4. Tas (heap) et file de priorité
Un tas-min (min-heap) est un arbre binaire (souvent représenté par un simple tableau) vérifiant la propriété de tas : la valeur de chaque nœud est inférieure ou égale à celles de ses enfants. Conséquence : la racine contient toujours le minimum de l'ensemble.
Opérations : insérer un élément : on l'ajoute en fin de tableau puis on le fait « remonter » (percolation vers le haut) tant qu'il est plus petit que son parent — coût . Extraire le minimum : on retire la racine, on la remplace par le dernier élément, puis on fait « descendre » cet élément (percolation vers le bas) — coût également.
Représentation par tableau : pour un nœud à l'indice (indexation à partir de ), son enfant gauche est à l'indice , son enfant droit à , son parent à — pas besoin de pointeurs explicites.
Application — file de priorité : un tas implémente efficacement une file de priorité (extraire systématiquement l'élément de plus haute/basse priorité), utilisée notamment dans l'algorithme de Dijkstra (leçon suivante) et le tri par tas (heapsort, dans tous les cas, y compris le pire).
5. Table de hachage
Une table de hachage associe à chaque clé un indice dans un tableau via une fonction de hachage , permettant insertion, recherche et suppression en en moyenne (sous hypothèse de bonne répartition des clés). En cas de collision (deux clés ayant le même indice), on utilise le chaînage (liste des éléments en collision à chaque case) ou l'adressage ouvert (recherche de la case libre suivante selon une règle déterministe).
Pire cas : si toutes les clés se retrouvent dans la même case (table de hachage mal conçue ou attaque délibérée), mais ce cas est rare en pratique avec une bonne fonction de hachage.
6. Récapitulatif
| Structure | Insertion | Recherche | Suppression |
| Pile / file | — | ||
| ABR équilibré | |||
| ABR non équilibré (pire cas) | |||
| Tas (min/max) | — (extraction min/max : ) | ||
| Table de hachage (moyenne) |
Exercices de la leçon
Exercice 1
Quelle est la règle de fonctionnement d'une pile (stack) ?
Corrigé
Une pile suit la règle LIFO (Last In, First Out) : on ne peut accéder/retirer qu'au sommet, qui est le dernier élément empilé.
Exercice 2
Vrai ou faux : dans un arbre binaire de recherche (ABR), toutes les valeurs du sous-arbre gauche d'un nœud sont inférieures à la valeur de ce nœud.
Corrigé
Vrai. C'est exactement la propriété définissante d'un ABR, qui garantit que la recherche peut se faire en suivant un unique chemin de la racine à la feuille, comme une dichotomie sur un arbre.
Exercice 3
Dans un tas-min, où se trouve toujours l'élément minimal ?
Corrigé
Par la propriété de tas-min (chaque nœud ses enfants), le minimum global se trouve nécessairement à la racine.
Exercice 4
Vrai ou faux : dans un tas représenté par un tableau (indexation à partir de 0), l'enfant gauche du nœud d'indice se trouve à l'indice .
Corrigé
Vrai. C'est la formule standard de représentation d'un tas par tableau : enfant gauche à , enfant droit à , parent à .
Exercice 5
Quelle est la complexité moyenne de la recherche d'une clé dans une table de hachage bien conçue ?
Corrigé
Avec une bonne fonction de hachage répartissant uniformément les clés, le nombre moyen de collisions par case reste constant, donc la recherche se fait en temps constant en moyenne — même si le pire cas reste .
Exercice 6
Un arbre binaire de recherche est construit en insérant successivement (déjà triés). Quelle est sa hauteur, et pourquoi ?
Corrigé
Comme les valeurs sont insérées dans l'ordre croissant, chaque nouvelle valeur est toujours supérieure à toutes les précédentes : elle devient l'enfant droit du dernier nœud inséré. L'arbre dégénère en une « liste chaînée » de hauteur .
Exercice 7
Pourquoi les arbres AVL ou rouge-noir garantissent-ils pour les opérations de base, contrairement à un ABR naïf ?
Corrigé
Les arbres équilibrés effectuent des rotations locales après chaque insertion/suppression pour garantir que la hauteur reste même dans le pire cas, contrairement à un ABR naïf qui peut dégénérer en hauteur .
Exercice 8
Pour insérer un élément dans un tas-min de taille (le tas étant un tableau), quelle est la complexité de l'opération ?
Corrigé
On ajoute l'élément en fin de tableau (), puis on le fait remonter (percolation) le long d'un chemin de la feuille à la racine, dont la longueur est au plus la hauteur du tas, soit (un tas est toujours quasi-complet, donc sa hauteur est ).
Exercice 9
Vrai ou faux : une file (queue) FIFO est adaptée pour implémenter un parcours en largeur (BFS) d'un graphe.
Corrigé
Vrai. Le parcours en largeur explore les sommets niveau par niveau ; en enfilant les voisins découverts et en défilant dans l'ordre de découverte (FIFO), on garantit que tous les sommets d'un niveau sont traités avant ceux du niveau suivant.
Exercice 10
Combien de comparaisons au minimum (dans le pire cas) sont nécessaires pour trouver le minimum d'un tableau non trié de éléments, et pourquoi ne peut-on pas faire mieux ?
Corrigé
Borne supérieure ( comparaisons suffisent). Un algorithme simple parcourt le tableau en gardant en mémoire le minimum courant, comparé à chaque nouvel élément : cela fait exactement comparaisons pour éléments.
Borne inférieure ( comparaisons sont nécessaires). Argument par un graphe de « tournoi » : chaque comparaison élimine un candidat possible au rang de minimum (le plus grand des deux comparés ne peut plus être le minimum). Pour identifier avec certitude le minimum parmi éléments, il faut « éliminer » les autres candidats, chacun nécessitant d'avoir perdu au moins une comparaison. Comme chaque comparaison n'élimine qu'un seul candidat (celui qui s'avère le plus grand des deux), il faut au moins comparaisons.
Conclusion : est à la fois suffisant et nécessaire — l'algorithme naïf de parcours linéaire est donc déjà optimal pour ce problème.
Exercice 11
Démontrer que la hauteur minimale d'un arbre binaire à nœuds est , en utilisant le fait qu'un arbre binaire de hauteur a au plus nœuds.
Corrigé
Borne sur le nombre de nœuds. Un arbre binaire de hauteur (la racine étant à hauteur ) a au plus nœuds (un nœud à la racine, au plus au niveau suivant, etc., somme géométrique).
Inversion de l'inégalité. Si l'arbre a nœuds, alors nécessairement , soit . En prenant le logarithme en base :
Conclusion. La hauteur est donc minorée par . Cette borne est atteinte exactement par un arbre parfaitement équilibré (chaque niveau totalement rempli, sauf éventuellement le dernier) — c'est précisément ce que garantissent les arbres AVL ou rouge-noir, justifiant que leurs opérations de base sont en dans le pire cas.
Exercice 12
Construire (par insertions successives) un tas-min à partir de la séquence (insertion une à une, dans cet ordre), et donner le tableau final.
Corrigé
On insère chaque élément en fin de tableau, puis on le fait « remonter » (percoler) tant qu'il est inférieur à son parent.
Insertion de 5 : tableau .
Insertion de 3 : . Le parent de l'indice est l'indice (valeur ). Comme , on échange : .
Insertion de 8 : . Le parent de l'indice est l'indice (valeur ). Comme , pas d'échange : .
Insertion de 1 : . Le parent de l'indice est l'indice (valeur ). Comme , échange : . Le parent de l'indice est maintenant l'indice (valeur ). Comme , échange : .
Insertion de 9 : . Le parent de l'indice est l'indice (valeur ). Comme , pas d'échange.
Tableau final : , qui correspond bien à un tas-min valide (on vérifie : parent de l'indice = indice = ✓ ; parent de l'indice = indice = ✓ ; parent de l'indice = indice = ✓).
Exercice 13
Vrai ou faux : le tri par tas (heapsort) a une complexité dans le pire cas, contrairement au tri rapide (quicksort) dont le pire cas est .
Corrigé
Vrai. Le tri par tas construit un tas en , puis extrait le minimum (ou maximum) fois, chaque extraction coûtant — soit dans tous les cas, sans dépendre de la configuration initiale des données, contrairement au tri rapide qui peut se dégrader en sur certaines entrées défavorables.
Exercice 14
Expliquer pourquoi une table de hachage peut se dégrader à pour la recherche dans le pire cas, et quelles stratégies permettent de limiter ce risque en pratique.
Corrigé
Origine du pire cas. Une table de hachage répartit les clés dans des cases via une fonction de hachage . Si, pour une raison quelconque (mauvaise fonction de hachage, ou distribution adversariale des clés), un grand nombre de clés se retrouvent dans la même case, la structure de chaînage associée à cette case devient une simple liste, et la recherche d'un élément dans cette liste coûte où est le nombre de clés en collision — dans le pire cas, (toutes les clés dans la même case), donnant .
Stratégies de limitation en pratique :
1. Bonne fonction de hachage : choisir de sorte que les clés réelles (pas seulement théoriques) se répartissent le plus uniformément possible sur les cases disponibles.
2. Hachage universel (aléatoire) : tirer aléatoirement la fonction de hachage parmi une famille de fonctions au démarrage du programme, rendant impossible pour un adversaire de construire à l'avance un ensemble de clés provoquant systématiquement des collisions massives (attaque par déni de service sur les tables de hachage).
3. Redimensionnement dynamique (rehachage) : quand le facteur de charge (nombre de clés / nombre de cases) dépasse un seuil, on agrandit la table et on réinsère toutes les clés, ce qui maintient les chaînes courtes en moyenne.
4. Structures hybrides : remplacer les listes de chaînage par des arbres équilibrés au-delà d'un certain seuil de collisions dans une case (stratégie utilisée par certaines implémentations modernes de tables de hachage), garantissant même dans le pire cas d'une case surchargée.
Exercice 15
Démontrer que, dans un tas-min représenté par un tableau de taille (indexation à partir de ), le nombre de feuilles est exactement .
Corrigé
Caractérisation des feuilles. Un nœud d'indice (pour ) est une feuille si et seulement s'il n'a pas d'enfant gauche, c'est-à-dire si l'indice de son enfant gauche, , dépasse ou égale :
Comptage des indices vérifiant cette condition. Comme est un entier, la condition équivaut à . Les indices valides sont donc , soit un nombre d'éléments égal à :
(on vérifie directement sur des petits cas : donne les indices , soit , donc feuilles ; donne , soit , donc feuilles).
Conclusion : le nombre de feuilles d'un tas à nœuds est exactement . Ce résultat est notamment utilisé pour borner le coût de la construction d'un tas en (et non comme on pourrait naïvement le penser), car la majorité des nœuds (environ la moitié) sont des feuilles ne nécessitant aucune percolation.
AlphaMath Académie · Structures de données : piles, files, arbres et tas · Informatique L3 — Algorithmique, structures de données et graphes