Terminale · Structures de données

Structures de données : interface et implémentation

Un même bouton « défiler » peut masquer un tableau ou deux piles. Si les opérations respectent le même contrat, le programme utilisateur obtient les mêmes résultats. Cette séparation permet de raisonner sur les besoins avant de choisir le mécanisme interne.

SofienAvec SofienIngénieur et enseignant en informatique
Dans ce chapitre

Un cap pour ce chapitre

Ce que vous saurez faire

  • Spécifier les opérations d’une structure.
  • Distinguer interface et implémentation.
  • Comparer deux réalisations d’un même comportement.
Les bases utiles pour commencer

Décrire ce que la structure permet

Une interface décrit les opérations accessibles et leur contrat. Pour une file, on peut proposer créer une file vide, tester si elle est vide, enfiler un élément et défiler l’élément le plus ancien. L’interface précise les paramètres, les résultats, les effets et les conditions d’utilisation. Défiler peut par exemple exiger une file non vide.

Cette description n’impose pas l’organisation en mémoire. Elle indique ce qu’un programme peut demander et ce qu’il peut attendre en retour. Pour l’utiliser correctement, il doit respecter les préconditions ; pour la réaliser correctement, l’implémentation doit garantir les postconditions.

Le contrat doit aussi préciser ce qui ne change pas. Après un retrait, les autres visiteurs restent dans le même ordre. Après une consultation de tête, la taille reste identique. Ces garanties rendent possible un raisonnement sur le programme client sans connaître les cases ni les liens utilisés. Une opération correctement nommée mais insuffisamment spécifiée laisse encore plusieurs comportements incompatibles.

Réaliser le contrat avec un tableau

Une première file peut utiliser une liste Python dont le premier élément est le plus ancien. Enfiler ajoute à droite et défiler retire à gauche. Une autre réalisation peut conserver les éléments dans l’ordre inverse : enfiler à gauche et défiler à droite. Les listes internes diffèrent, mais l’ordre de sortie reste celui des arrivées.

Ces réalisations ne présentent pas nécessairement les mêmes coûts. Déplacer les éléments pour retirer ou ajouter au début d’une liste peut demander un travail proportionnel à sa longueur. La bonne abstraction ne nie pas cette différence ; elle permet de l’étudier séparément du comportement observable.

Changer le mécanisme sans changer le client

Supposons un programme d’accueil qui enfile les visiteurs puis les appelle avec défiler. S’il n’accède qu’aux opérations de l’interface, on peut remplacer le tableau par une réalisation à deux piles sans modifier sa logique. S’il lit directement la case interne 0, il dépend au contraire d’un détail qui peut changer.

Cette discipline facilite les tests. On applique la même suite d’opérations à plusieurs réalisations et on compare les sorties. Une différence révèle un défaut de contrat ou d’implémentation. Des tests réussis ne prouvent pas tous les cas, mais constituent une vérification concrète de l’interchangeabilité annoncée.

Un test commun doit observer les résultats publics et les effets prévus, pas comparer les listes internes. Sinon il déclarerait à tort différente une réalisation qui range les données autrement. Pour tester une file, on peut enregistrer les valeurs renvoyées par les retraits, consulter sa taille si cette opération est exposée et vérifier les refus prévus aux limites.

Choisir des limites explicites

Une file de capacité limitée doit définir ce qui arrive lorsqu’elle est pleine. Une file vide doit également avoir un comportement prévu si une opération de retrait est demandée. On peut imposer une précondition ou produire une erreur documentée ; renvoyer arbitrairement une valeur qui pourrait aussi être une donnée valide créerait une ambiguïté.

L’atelier compare deux listes internes opposées. Il affiche les opérations interdites comme des refus sans modifier la structure. Ce choix pédagogique n’oblige pas toutes les files à gérer les erreurs de cette manière. Le but est d’observer un contrat commun malgré des représentations différentes.

Exemple suivi : rédiger une petite interface

Une file de commandes propose creer(), est_vide(f), enfiler(f,x) et defiler(f). Créer fournit une file vide. Tester la vacuité renvoie un booléen sans modification. Enfiler ajoute x après les éléments présents. Défiler exige une file non vide, renvoie le plus ancien élément puis le retire, sans changer l’ordre des autres.

À partir du vide, enfilez A, enfilez B, défilez, enfilez C, puis défilez deux fois. Les sorties doivent être A,B,C, quelle que soit la représentation. Les états abstraits sont [], [A], [A,B], [B], [B,C], [C], []. Cette trace définit ce qui est observable. Une représentation stockant les éléments à l’envers doit adapter ses opérations pour reproduire exactement cette suite.

Adapter une implémentation et diagnostiquer ses limites

Supposons une capacité de deux éléments. Après l’arrivée de A et B, enfiler C doit suivre une règle documentée : refus avec état conservé, erreur ou autre politique explicitement choisie. Remplacer silencieusement A par C changerait la notion de file si l’interface ne l’autorise pas. Une capacité est une contrainte observable, elle ne peut pas être cachée comme un simple détail interne.

Pour choisir une réalisation, séparez conformité et coût. Une liste peut retirer au début en déplaçant plusieurs cases ; une autre organisation peut éviter ces déplacements mais utiliser davantage de références. Les résultats peuvent rester identiques. Le choix dépend des opérations fréquentes, des tailles et de la simplicité souhaitée. L’abstraction sert à garder stable le besoin exprimé par le client, tout en permettant d’étudier ces compromis et de remplacer le mécanisme lorsque ses garanties restent compatibles.

À vous de faire varier les choses

Une file, deux rangements internes

Choisissez une suite d’arrivées et de départs. Avancez les opérations et vérifiez que les sorties sont identiques malgré les listes inversées.

Lire le résultat de l’expérience initiale

Sorties : A

I range le plus ancien à gauche ; II le range à droite. Les opérations du contrat doivent produire les mêmes sorties.

OpérationInterne IInterne IIRésultat I / II
Enfiler AAAArrivée acceptée
Enfiler BA, BB, AArrivée acceptée
DéfilerBBA / A

Le contrat reste stable quand les opérations internes s’adaptent au rangement choisi.

De la compréhension à l’autonomie

À vous de résoudre

Cherchez d’abord par vous-même. Vérifiez les résultats demandés, utilisez les indices si nécessaire, puis comparez votre méthode à la correction.

Exercice 1 · Comprendre#

Lire le contrat

Une opération défiler exige une file non vide et renvoie son élément le plus ancien en le retirant. Identifiez précondition, résultat et effet.

Indice 1

Une précondition doit être vraie avant l’appel.

Indice 2

Renvoyer et retirer sont deux propriétés différentes.

Comprendre la correction

La précondition est que la file soit non vide. Le résultat est l’élément entré depuis le plus longtemps parmi ceux encore présents. L’effet est son retrait de la file. Une fonction qui le renverrait sans le retirer respecterait seulement une partie du contrat.

Exercice 2 · Appliquer#

Deux représentations, une sortie

Une file a reçu A, B puis C. L’implémentation I stocke [A, B, C], la II [C, B, A]. Quel élément doit sortir et de quel côté chaque réalisation le retire-t-elle ?

Indice 1

Le premier arrivé reste le même dans les deux cas.

Indice 2

Le côté du retrait dépend de la représentation.

Comprendre la correction

A doit sortir dans les deux cas. La réalisation I retire à gauche, tandis que la II retire à droite. Les contenus internes sont inversés, mais la signification de l’opération reste identique. Retirer à droite dans les deux versions ne respecterait pas le même contrat.

Exercice 3 · Corriger#

Un client trop curieux

Un programme utilise file.contenu[0] pour obtenir le prochain visiteur. Pourquoi cette instruction fragilise-t-elle le remplacement de la file ?

Indice 1

La première case n’a pas forcément le même sens dans toutes les réalisations.

Indice 2

Cherchez une opération publique exprimant le besoin.

Comprendre la correction

Le programme dépend de l’existence d’un attribut contenu et du choix de ranger le plus ancien élément à l’indice 0. Une autre réalisation peut utiliser deux piles ou un ordre inverse. Il faut demander une opération d’interface, comme consulter la tête, dont le contrat garantit le prochain élément sans exposer son rangement.

Exercice 4 · Justifier#

L’équivalence ne garantit pas le même coût

Deux files renvoient les mêmes éléments pour toute suite d’opérations valide. Peut-on en déduire qu’elles consomment autant de temps et de mémoire ?

Indice 1

Le comportement observable et la réalisation sont séparés.

Indice 2

Les déplacements internes peuvent différer.

Comprendre la correction

Non. L’équivalence du comportement garantit les mêmes résultats et effets définis par l’interface, pas les mêmes coûts. Une réalisation peut déplacer de nombreux éléments, une autre utiliser des liens ou différer des transferts. Il faut analyser les opérations internes et la mémoire nécessaire selon l’usage attendu.

Exercice 5 · Approfondir et transférer#

Une suite qui sépare pile et file

Depuis une structure vide, ajoutez 4, ajoutez 7, retirez, ajoutez 2, retirez, retirez. Donnez les sorties attendues pour une file puis pour une pile. Expliquez pourquoi ce test distingue les deux contrats malgré les mêmes noms de méthodes.

Indice 1

La file retire le plus ancien ; la pile retire le plus récent.

Indice 2

Conservez le contenu restant après chaque retrait.

Comprendre la correction

Pour la file, les sorties sont 4,7,2. Pour la pile, elles sont 7,2,4. Les structures utilisent les mêmes valeurs et peuvent exposer des noms proches, mais elles n’offrent pas le même ordre. Ce scénario est donc plus informatif que l’ajout puis le retrait d’un unique élément.

Exercice 6 · Approfondir et transférer#

Le refus doit préserver la file

Une file de capacité deux refuse un ajout lorsque sa taille atteint deux. On ajoute A,B,C, puis on retire deux fois. Donnez les sorties et l’état après le refus. Un programme qui remplace A par C respecte-t-il cette interface ?

Indice 1

Le refus annoncé ne retire aucun élément ancien.

Indice 2

Les effets interdits font aussi partie du contrat.

Comprendre la correction

Après le refus de C, la file reste A,B. Les sorties sont A puis B. Remplacer A par C détruit une commande acceptée auparavant et viole le contrat de refus sans modification. La limitation de capacité n’autorise pas implicitement une politique d’écrasement.

Exercice 7 · Approfondir et transférer#

Un client indépendant

Un client veut afficher le prochain visiteur sans le retirer. Il lit actuellement f.contenu[0]. Proposez une opération publique avec précondition, résultat et effet. Expliquez comment une représentation inversée peut la réaliser.

Indice 1

Le besoin est une consultation et non un retrait.

Indice 2

La position interne du plus ancien dépend du rangement.

Comprendre la correction

On peut définir tete(f) avec précondition file non vide, résultat égal au plus ancien élément et aucun effet sur la file. Une représentation normale consulte sa première case ; une représentation inversée consulte la dernière. Le client appelle la même opération et conserve sa logique, sans connaître le rangement.

Les erreurs qui méritent un détour

Définir une interface comme un écran graphique.
Ici, le mot désigne le contrat des opérations offertes à un programme. Le contexte détermine son sens.
Supposer qu’une représentation correcte est optimale.
Un même contrat peut admettre plusieurs compromis de temps, mémoire et simplicité.

La fiche à garder

L’essentiel à retenir

  • L’interface décrit les opérations et leurs contrats.
  • L’implémentation réalise ces opérations avec une organisation concrète.
  • Un client fondé sur l’interface dépend moins des détails internes.

Le prochain pas

Retrouver le catalogue de Terminale

Ce chapitre s’appuie sur le programme officiel de Terminale (PDF, nouvel onglet). Les explications et exercices sont proposés pour l’apprentissage.