3.1 Introduction aux structures de données et aux algorithmes
Objectifs d'apprentissage
À la fin de cette section, vous serez capable de :
- Comprendre la différence entre les algorithmes et les programmes
- Établir un lien entre les structures de données et les types abstraits de données
- Sélectionner la structure de données appropriée pour résoudre un problème donné de manière pratique
L'informatique est l'étude des ordinateurs et des systèmes de calcul qui impliquent la représentation des données et l'automatisation des processus. En raison de leurs racines historiques en tant que calculatrices, les ordinateurs peuvent facilement représenter des données numériques. Les calculatrices s'appuient sur des algorithmes pour additionner, soustraire, multiplier et diviser des nombres. Mais qu'en est-il des données plus complexes ? Comment les ordinateurs représentent-ils des objets complexes comme des graphes, des images, des vidéos ou des phrases ? Quelles complications surviennent lorsque nous représentons ou traitons des données de certaines manières ? Ce sont quelques-unes des questions fondamentales sur lesquelles les informaticiens et les programmeurs se concentrent lors de la conception de logiciels et d'applications que nous utilisons pour résoudre des problèmes.
Un type de données (data type) détermine la manière dont les ordinateurs traitent les données en définissant les valeurs possibles pour les données et les fonctionnalités ou opérations possibles sur ces données. Par exemple, le type de données entier (integer data type) est défini comme des valeurs provenant d'une certaine plage de nombres entiers positifs ou négatifs, avec des fonctionnalités incluant l'addition, la soustraction, la multiplication et la division. Le type chaîne de caractères (string data type) est défini comme une séquence de caractères où chaque caractère peut être une lettre, un chiffre, un signe de ponctuation ou un espace, avec des fonctionnalités qui incluent l'ajout ou la suppression d'un caractère d'une chaîne, la concaténation de chaînes et la comparaison de deux chaînes basée, par exemple, sur leur ordre alphabétique.
Les types de données comme les chaînes de caractères sont un exemple d'abstraction (abstraction), le processus de simplification d'un concept afin de le représenter dans un ordinateur. Le type chaîne de caractères prend un concept complexe comme une phrase et le représente en termes de données plus basiques avec lesquelles un ordinateur peut travailler. Lorsqu'un ordinateur compare deux chaînes, il compare en réalité les codes numériques de caractères individuels (voir Chapitre 5 Réalisations matérielles des algorithmes : Conception des systèmes informatiques) correspondant à chaque paire de caractères au sein des deux chaînes.
Dans cette section, nous apprendrons à résoudre des problèmes en choisissant des abstractions pour les données complexes. Nous verrons que, tout comme nos données deviennent plus complexes, nos algorithmes le deviennent aussi.
Introduction aux algorithmes
Un algorithme est une séquence d'instructions précises qui opèrent sur des données. Nous pouvons considérer les recettes, les plans ou les instructions de notre vie quotidienne comme des exemples d'algorithmes. Les ordinateurs ne peuvent exécuter qu'un ensemble fini d'instructions prédéfinies exactement comme indiqué, c'est pourquoi la programmation peut sembler une manière de communiquer si différente par rapport à nos langages humains naturels. Un programme (program) est une implémentation (réalisation) d'un algorithme écrit dans un langage de programmation formel.
Bien que chaque langage de programmation soit différent de tous les autres, il existe des idées communes à tous. La connaissance de quelques-unes de ces idées communes permet aux informaticiens d'aborder une grande variété de problèmes sans avoir à repartir de zéro à chaque fois. Par exemple, l'abstraction des données de type chaîne de caractères permet aux programmeurs d'écrire des programmes qui opèrent sur des lettres, des chiffres, des signes de ponctuation ou des espaces lisibles par l'homme sans avoir à déterminer comment approfondir chacun de ces concepts. Les langages de programmation nous permettent de définir des abstractions pour représenter des idées dans un ordinateur (voir Chapitre 4 Réalisation linguistique des algorithmes : Langages de programmation de bas niveau pour plus de détails).
L'étude des structures de données et des algorithmes se concentre sur l'identification de ce que l'on appelle un algorithme canonique (canonical algorithm) : un algorithme bien connu qui met en évidence des principes de conception utiles pour une grande variété de problèmes. Dans ce chapitre, plutôt que de nous concentrer sur les détails de programmation, nous nous concentrerons sur les algorithmes et les idées qui les sous-tendent.
Comprendre les structures de données
Pour de nombreux problèmes du monde réel, la capacité à concevoir un algorithme dépend de la manière dont les données sont représentées. Une structure de données (data structure) est un type de données complexe (complex data) avec deux parties d'égale importance :
- une représentation (representation) spécifique ou une manière d'organiser une collection de plus d'un élément (element), qui est une valeur individuelle ou un point de données, et
- une fonctionnalité (functionality) spécifique ou des opérations telles que l'ajout, la récupération et la suppression d'éléments.
Dans notre exemple précédent, une chaîne de caractères est une structure de données pour représenter des phrases comme une séquence de caractères. Elle possède des fonctionnalités spécifiques telles que l'insertion ou la suppression de caractères, la concaténation de chaînes et la comparaison de chaînes.
Bien que les valeurs pour les données complexes soient souvent diverses, les informaticiens ont conçu des structures de données de manière à ce qu'elles puissent être réutilisées pour d'autres problèmes. Par exemple, plutôt que de concevoir une structure de données spécialisée pour les phrases dans chaque langue humaine, nous utilisons souvent une seule structure de données universelle de type chaîne de caractères pour représenter des phrases, y compris des caractères de différentes langues dans la même phrase. (Nous verrons plus tard certains inconvénients des hypothèses de généralisation dans la conception des structures de données et des algorithmes.) De plus, les ordinateurs prennent du temps pour exécuter des algorithmes, c'est pourquoi les informaticiens se préoccupent de l'efficacité en termes de temps nécessaire à un algorithme pour calculer un résultat.
Parmi les différents types de structures de données universelles, les informaticiens ont trouvé utile de catégoriser les structures de données en fonction de leur fonctionnalité sans considérer leur représentation spécifique. Un type abstrait de données (ADT) consiste en toutes les structures de données qui partagent une fonctionnalité commune mais diffèrent par leur représentation spécifique.
Les types abstraits de données courants pour les données complexes sont les suivants, et les types liste et ensemble sont présentés dans la Figure 3.2. Nous discuterons de chaque type abstrait de données plus en détail, ainsi que de leurs implémentations de structures de données.
- Une liste (list) représente une séquence ordonnée d'éléments et permet d'ajouter, de récupérer et de supprimer des éléments de n'importe quelle position dans la liste. Les listes sont indexées car elles permettent d'accéder aux éléments en se référant à l'index (index) de l'élément, qui est la position ou l'adresse d'un élément dans la liste. Par exemple, une liste peut être utilisée pour représenter une liste de tâches, où chaque élément de la liste est la prochaine tâche à accomplir par ordre chronologique.
- Un ensemble (set) représente une collection non ordonnée d'éléments uniques et permet d'ajouter, de récupérer et de supprimer des éléments de l'ensemble. Les ensembles offrent généralement moins de fonctionnalités que les listes, mais cette réduction de fonctionnalité permet des représentations de structures de données plus efficaces. Par exemple, un ensemble peut être utilisé pour représenter les noms de tous les lieux que vous souhaitez visiter à l'avenir.
- Une carte (map) représente des associations non ordonnées entre des paires clé-valeur d'éléments, où chaque clé ne peut apparaître qu'une seule fois dans la carte. Une carte est également connue sous le nom de dictionnaire (dictionary) puisque chaque terme (clé) a une définition associée. Les cartes sont souvent utilisées en combinaison avec d'autres structures de données. Par exemple, une carte peut être utilisée pour représenter une liste de souhaits de voyage : chaque lieu que vous souhaitez visiter à l'avenir peut être associé à la liste des choses que vous voulez faire lorsque vous arrivez à un endroit donné.
- Une file de priorité (priority queue) représente une collection d'éléments où chaque élément a une valeur de priorité associée. En plus d'ajouter des éléments, les files de priorité se concentrent sur la récupération et la suppression de l'élément ayant la priorité la plus élevée. Par exemple, une file de priorité peut être utilisée pour représenter le traitement des patients hospitalisés dans un service d'urgence hospitalier : les patients ayant un besoin de soins plus urgent peuvent être prioritaires et traités en premier.
- Un graphe (graph) représente des relations binaires entre une collection d'entités. Plus précisément, les entités sont représentées comme des sommets dans le graphe, et une arête dirigée ou non dirigée est ajoutée entre deux sommets pour représenter la présence ou l'absence d'une certaine relation. Par exemple, un graphe d'amitié peut être utilisé pour représenter les relations d'amitié entre des personnes, auquel cas une arête non dirigée est ajoutée entre deux personnes si elles sont amies. Les graphes permettent des opérations telles que l'ajout de sommets et d'arêtes, la suppression de sommets et d'arêtes, et la récupération de toutes les arêtes adjacentes à un sommet donné.
Sélectionner une structure de données
Étant donné que la représentation de données (data representation) est une tâche fondamentale dans la conception d'algorithmes (algorithm) qui résolvent des problèmes, comment sélectionnons-nous les structures de données (data structure) pour un problème particulier ? Les informaticiens appliquent une approche descendante (top-down approach).
- Sélectionner un type abstrait de données approprié en analysant le problème pour déterminer la fonctionnalité et les opérations nécessaires.
- Sélectionner une structure de données appropriée en quantifiant les contraintes de ressources (généralement le temps d'exécution du programme) pour chaque opération.
La principale préoccupation est les données et les opérations à effectuer sur celles-ci. En repensant aux types de données simples comme les nombres, nous nous sommes concentrés sur l'addition, la soustraction, la multiplication et la division comme opérations de base. De même, pour représenter des types de données complexes, nous nous concentrons également sur les opérations qui soutiendront le plus directement nos algorithmes. Après avoir choisi un type abstrait de données, nous sélectionnons ensuite une structure de données particulière qui implémente ce type abstrait de données.
Structures de données linéaires
Si un problème peut être résolu avec une séquence ordonnée d'éléments (element), l'approche la plus simple pourrait être de les stocker dans une liste. Certains problèmes exigent que les actions soient effectuées dans un ordre chronologique strict, comme le traitement des éléments dans l'ordre de leur arrivée ou dans l'ordre inverse. Dans ces situations, une structure de données linéaire (linear data structure), qui est une catégorie de structures de données où les éléments sont ordonnés en ligne, est appropriée. Il existe deux implémentations possibles pour le type abstrait de données liste. La première, une liste de tableau (array list) (Figure 3.3), est une structure de données qui stocke les éléments de la liste côte à côte en mémoire. L'autre est une liste chaînée (linked list) (Figure 3.4), qui est une structure de données de liste qui ne stocke pas nécessairement les éléments de la liste côte à côte, mais fonctionne plutôt en maintenant, pour chaque élément, un lien vers l'élément suivant dans la liste. Les listes de tableaux et les listes chaînées sont toutes deux des structures de données linéaires car leurs éléments sont organisés en ligne, l'un après l'autre. Un avantage des listes de tableaux est qu'elles permettent un accès (aléatoire) à chaque élément de la liste en une seule étape. Cela contraste fortement avec les listes chaînées, qui ne prennent en charge que l'« accès séquentiel ». D'autre part, les listes chaînées prennent en charge des opérations d'insertion et de suppression rapides, ce que les listes de tableaux ne font pas.
Plus tôt, nous avons présenté les ensembles comme offrant moins de fonctionnalités que les listes. Les listes de tableaux et les listes chaînées peuvent également implémenter le type abstrait de données ensemble (set). Les ensembles diffèrent des listes de deux manières : les ensembles sont non ordonnés — les éléments ne se voient donc pas attribuer de positions spécifiques — et les ensembles ne sont composés que d'éléments uniques. En plus d'implémenter les ensembles, les structures de données linéaires peuvent également implémenter les types abstraits de données carte, file de priorité et graphe. Si les structures de données linéaires peuvent couvrir un si large éventail de types abstraits de données, pourquoi apprendre d'autres structures de données ? En théorie, toute donnée complexe peut être représentée avec une liste de tableau ou une liste chaînée, bien que cela puisse ne pas être optimal, comme nous l'expliquerons plus en détail.
Un inconvénient de ne s'appuyer que sur des structures de données linéaires est lié au concept d'efficacité. Même si les structures de données linéaires peuvent résoudre n'importe quel problème, nous pourrions préférer des structures de données plus spécialisées qui peuvent résoudre moins de problèmes plus efficacement et aider à représenter plus fidèlement les arrangements de données du monde réel. Cela est particulièrement utile lorsque nous avons de grandes quantités de données comme des lieux ou des routes dans une carte en ligne du monde entier. Les structures de données linéaires organisent finalement les éléments en ligne, ce qui est nécessaire pour implémenter les listes mais pas pour d'autres types abstraits de données. D'autres structures de données se spécialisent dans l'implémentation d'ensembles, de cartes et de files de priorité en organisant les éléments dans une hiérarchie plutôt qu'en ligne.
Structures de données arborescentes
Un arbre (tree) est une structure de données hiérarchique. Bien qu'il existe de nombreux types de structures de données arborescentes, toutes partagent la même structure d'organisation de base : un nœud (node) représente un élément dans un arbre ou un graphe. Un nœud peut ou non avoir un descendant. Un nœud enfant (child node) est un descendant d'un autre nœud. Souvent, le nœud principal est appelé « nœud parent (parent node) ». Les arbres maintiennent une hiérarchie par le biais de relations parent-enfant, qui se répètent du nœud racine (root node) au sommet de l'arbre jusqu'à chaque nœud feuille (leaf node), qui se trouve au bas de l'arbre et n'a pas d'enfants. La hauteur d'un arbre correspond à la profondeur de la hiérarchie des descendants. La Figure 3.5 illustre la structure et les éléments d'un arbre.
Arbres binaires de recherche
Un arbre binaire de recherche (binary search tree) est un type de structure de données arborescente souvent utilisé pour implémenter des ensembles et des cartes avec la propriété d'arbre binaire (binary tree property), qui exige que chaque nœud puisse avoir zéro, un ou deux enfants, et la propriété d'arbre de recherche (search tree property), qui exige que les éléments de l'arbre soient organisés du plus petit au plus grand de gauche à droite. En d'autres termes, les valeurs de tous les éléments du sous-arbre gauche d'un nœud ont une valeur inférieure à celle du nœud. De même, les valeurs de tous les éléments du sous-arbre droit d'un nœud ont une valeur supérieure à celle du nœud. La propriété d'arbre de recherche suggère que lorsque les éléments sont lus de gauche à droite dans un arbre de recherche, nous obtiendrons les éléments dans l'ordre trié. Pour les nombres, nous pouvons comparer et trier les nombres par leurs valeurs numériques. Pour des données plus complexes comme des mots ou des phrases, nous pouvons les comparer et les trier par ordre alphabétique. Les arbres binaires de recherche utilisent ces propriétés intrinsèques des données pour organiser les éléments dans une hiérarchie consultable (Figure 3.6).
L'arbre illustré satisfait la propriété d'arbre binaire basée sur l'ordre alphabétique naturel entre les lettres puisque les éléments de l'arbre sont organisés du plus petit au plus grand de gauche à droite. En d'autres termes, pour une liste de lettres donnée, commencez au milieu de la liste de lettres avec D (le nœud racine), puis choisissez B comme sous-nœud gauche de D qui se trouve au milieu de la liste de lettres qui est à droite de D, et choisissez F comme sous-nœud droit de D, qui se trouve au milieu de la liste de lettres qui est à gauche de D. Enfin, organisez les lettres restantes sous les sous-nœuds B et F pour vous assurer qu'elles sont du plus petit au plus grand de gauche à droite.
La propriété d'arbre de recherche est responsable des améliorations d'efficacité par rapport aux structures de données linéaires. En stockant les éléments dans un ordre trié dans l'arbre de recherche plutôt que dans un ordre indexé dans une liste, les arbres binaires de recherche peuvent trouver un élément donné plus efficacement. Considérez comment nous pourrions rechercher des mots dans un dictionnaire. Un dictionnaire d'arbre binaire de recherche stockant tous les termes et leurs définitions associées peut permettre une recherche efficace en commençant au milieu du dictionnaire (le nœud racine) avant de déterminer s'il faut aller à gauche ou à droite en fonction de si nous nous attendons à ce que notre mot apparaisse plus tôt ou plus tard dans l'ordre alphabétique. Si nous répétons ce processus, nous pouvons éliminer à plusieurs reprises la moitié des éléments restants à chaque fois. La recherche d'un terme dans un dictionnaire basé sur une liste qui n'est pas trié, en revanche, nous obligerait à commencer au début de la liste et à considérer chaque mot jusqu'à la fin de la liste puisqu'il n'y a pas de structure d'ordonnancement sous-jacente aux éléments.
Arbres binaires de recherche équilibrés
Les arbres binaires de recherche ne sont pas aussi efficaces que nous l'avons décrit. L'exemple du dictionnaire représente un scénario du meilleur cas pour les arbres binaires de recherche. Nous ne pouvons éliminer la moitié des éléments restants à chaque fois que si l'arbre binaire de recherche est parfaitement équilibré (perfectly balanced), ce qui signifie que pour chaque nœud de l'arbre binaire de recherche, ses sous-arbres gauche et droit contiennent le même nombre d'éléments. C'est une exigence forte, car l'ordre dans lequel les éléments sont ajoutés à un arbre binaire de recherche détermine la forme de l'arbre. En d'autres termes, les arbres binaires de recherche peuvent facilement devenir déséquilibrés. Il est possible qu'un arbre binaire de recherche ressemble exactement à une liste chaînée, dans laquelle chaque nœud contient soit zéro enfant, soit un enfant, ce qui n'est pas plus efficace qu'une structure de données linéaire.
Un arbre AVL (AVL tree) (nommé d'après ses inventeurs, Adelson-Velsky et Landis) est une structure de données d'arbre binaire de recherche équilibré souvent utilisée pour implémenter des ensembles ou des cartes avec une propriété d'arbre supplémentaire : la propriété d'arbre AVL (AVL tree property), qui exige que les sous-arbres gauche et droit soient équilibrés à chaque nœud de l'arbre. Les arbres AVL ne sont qu'un parmi de nombreux arbres binaires de recherche « auto-équilibrants ». Un arbre binaire de recherche équilibré (balanced binary search tree) introduit des propriétés supplémentaires qui garantissent que l'arbre réorganise les éléments pour maintenir l'équilibre (Figure 3.7).
Les arbres binaires de recherche équilibrés tels que les arbres AVL représentent une seule approche pour garantir que l'arbre n'entre jamais dans une situation du pire cas. Il existe de nombreuses autres structures de données d'arbres binaires de recherche équilibrés en plus des arbres AVL. Les arbres binaires de recherche équilibrés peuvent également être utilisés pour implémenter le type abstrait de données file de priorité (priority queue) si les éléments sont ordonnés selon leur valeur de priorité. Mais les arbres de recherche équilibrés ne sont pas la seule façon d'implémenter les files de priorité.
Tas binaires
Les files de priorité se concentrent sur la récupération et la suppression des éléments de plus haute priorité en premier, l'ajout d'un élément (element) à une file de priorité implique également la spécification d'une valeur de priorité associée qui est utilisée pour déterminer quels éléments sont servis ensuite. Par exemple, les patients dans un service d'urgence pourraient être servis en fonction de la gravité de leurs problèmes de santé plutôt qu'en fonction de l'heure d'arrivée. Un tas binaire (binary heap) est un type de structure de données d'arbre binaire qui est également l'implémentation la plus courante pour le type abstrait de données file de priorité (Figure 3.8). Un tas binaire n'est pas un arbre de recherche, mais plutôt une structure de données hybride entre un arbre binaire et une liste de tableau. Les données sont stockées sous forme de liste de tableau en mémoire, mais le tas binaire aide à visualiser les données de la même manière qu'un arbre binaire, ce qui facilite la compréhension de la manière dont les données sont stockées et manipulées. Les tas binaires organisent les éléments selon la propriété de tas (heap property), qui exige que la valeur de priorité de chaque nœud dans le tas soit supérieure ou égale aux valeurs de priorité de ses enfants. La propriété de tas suggère que l'élément de plus haute priorité sera toujours le nœud racine où il est efficace d'accéder.
Concepts en pratique
Suivi des tremblements de terre
Les tremblements de terre, les ouragans, les tsunamis et autres catastrophes naturelles se produisent régulièrement et exigent souvent une réponse internationale. Comment suivre les catastrophes naturelles et identifier les zones les plus touchées afin de coordonner les efforts de secours et de soutien ? Aux États-Unis, l'U.S. Geological Survey (USGS) est responsable de la déclaration des tremblements de terre à l'aide de milliers de capteurs sismiques. Cependant, de nombreux endroits restent sans capteurs sismiques. En dehors des États-Unis, la technologie des capteurs peut être moins robuste ou inaccessible.
Les données des réseaux sociaux peuvent être utilisées pour améliorer ces informations et alerter plus rapidement les gouvernements sur les catastrophes naturelles en temps réel. En surveillant les plateformes de réseaux sociaux publiques pour les occurrences de messages courts tels que « tremblement de terre ? », nous pouvons rapidement localiser les tremblements de terre en fonction des données de géolocalisation de l'utilisateur. Cependant, l'agrégation et la compréhension de ces données — souvent des milliers de points de données arrivant en quelques minutes — nécessitent des structures de données et des algorithmes efficaces. Nous pouvons utiliser un tas binaire qui implémente le type abstrait de données file de priorité pour un programme de suivi des tremblements de terre. Pour chaque message « tremblement de terre ? » reçu pour une géolocalisation donnée, nous pouvons augmenter la priorité des emplacements de tremblement de terre, ce qui aide à identifier l'emplacement probable du tremblement de terre le plus proche de l'emplacement réel de l'utilisateur. À tout moment, nous pouvons récupérer efficacement l'élément de plus haute priorité de la file de priorité. En choisissant d'utiliser un tas binaire plutôt qu'une structure de données linéaire pour implémenter la file de priorité, nous pouvons nous assurer que le programme de suivi des tremblements de terre est capable de suivre les milliers de messages envoyés chaque minute lors d'un tremblement de terre.
Structures de données de graphe
Les structures de données d'arbres binaires de recherche et de tas binaires représentent des moyens plus efficaces d'implémenter des ensembles, des cartes et des files de priorité en organisant les données selon leurs propriétés intrinsèques. Dans les deux cas, les propriétés des données permettent l'ajout, la récupération et la suppression efficaces d'éléments.
Les graphes sont un type différent de type abstrait de données. Plutôt que de se concentrer sur l'ajout, la récupération et la suppression, les graphes (graph) se concentrent sur la modélisation explicite des relations entre les éléments. Les graphes permettent d'accéder non seulement aux éléments, mais aussi aux relations entre les éléments.
- Un sommet (vertex) représente un élément dans un graphe ou un type spécial de celui-ci, tel qu'un arbre.
- Une arête (edge) est la relation entre les sommets ou les nœuds. En option, les arêtes peuvent avoir des poids associés. Dans un type abstrait de données graphe, les relations entre deux sommets connectés par une arête sont considérées comme adjacents (adjacent).
Lien vers l'apprentissage
Visualgo est un site web qui propose des animations pour aider les utilisateurs à en apprendre davantage sur les algorithmes et les structures de données. Ils proposent des exercices pour aider à comprendre plusieurs concepts présentés dans ce chapitre. Vous pouvez accéder à des animations sur diverses structures de données et algorithmes tels qu'une liste chaînée, un arbre binaire de recherche et des structures de graphe.
Dans les réseaux informatiques tels que l'Internet, les graphes peuvent représenter des routeurs (router) de réseau individuels comme des nœuds (node) avec des paquets de données (data packet) circulant entre des routeurs directement connectés le long des arêtes. Même si tous les routeurs ne sont pas directement connectés à tous les autres routeurs, le routeur au nœud actuel peut analyser un paquet de données entrant pour déterminer par quelle arête il doit voyager ensuite. En répétant ce processus, un paquet de données peut voyager d'un routeur sur l'Internet à un autre routeur sur l'Internet même si les deux routeurs ne sont pas directement adjacents l'un à l'autre.
Les graphes sont uniques en ce qu'ils peuvent représenter directement une grande variété de problèmes du monde réel, tels que les suivants :
- Un réseau social (social network), où chaque sommet est une personne et chaque arête est une amitié.
- Le Web, où chaque sommet est une page web et chaque arête est un lien.
- Une carte (map) de campus, où chaque sommet est un bâtiment et chaque arête est un sentier piétonnier.
- Un diagramme de prérequis de cours, où chaque sommet est un cours et chaque arête est un prérequis.
Contrairement aux types abstraits de données liste, ensemble, carte et file de priorité, qui ont des fonctionnalités relativement standardisées axées sur l'ajout, la récupération et la suppression d'éléments, le type abstrait de données graphe est beaucoup moins standardisé. Généralement, les concepteurs d'algorithmes de graphe créeront leur propre type de données graphe pour représenter un problème. Le problème de graphe correspondant peut alors être représenté en utilisant ou en adaptant un algorithme de graphe standard. Contrairement à la programmation avec d'autres types abstraits de données, une grande partie du travail difficile de résolution d'un problème avec un graphe se produit lorsque les programmeurs décident ce que les sommets et les arêtes représentent, et quel algorithme de graphe serait approprié pour résoudre le problème. Ils doivent également considérer les conséquences de la manière dont ils représentent le problème.
Enjeux mondiaux de la technologie
Traçage des contacts
L'épidémiologie est l'étude de la propagation des maladies infectieuses à travers le monde. Au sein de l'épidémiologie, le traçage des contacts (contact tracing) tente d'identifier les cas confirmés de maladie et de limiter sa propagation en traçant les personnes contactées et en les isolant pour éviter qu'elles ne propagent davantage la maladie.
Les structures de données de graphe peuvent aider les épidémiologistes à gérer les données et les personnes impliquées dans le traçage des contacts. Imaginez un graphe où chaque sommet d'un graphe de traçage représente une personne, et chaque arête entre deux personnes représente un contact possible. Lorsqu'une personne reçoit un résultat de test positif pour avoir contracté la maladie, les professionnels de la santé peuvent identifier toutes les personnes avec lesquelles elle a été en contact en traçant à travers le graphe.
En plus d'améliorer la santé publique grâce au traçage des contacts, notre graphe imaginaire peut également représenter un historique de la propagation de la maladie pour que les épidémiologistes comprennent comment la maladie se déplace dans les communautés. Par exemple, si chaque sommet inclut des données de caractéristiques d'identité telles que l'âge, la race ou le sexe, les épidémiologistes peuvent étudier quels groupes de personnes sont les plus touchés par la maladie. Cela peut ensuite éclairer la distribution des vaccins pour aider en premier les groupes les plus touchés.
Données complexes
Maintenant que nous avons vu plusieurs implémentations de structures de données pour les données abstraites, examinons comment ces structures de données sont utilisées en pratique. Rappelons que nous avons comparé les calculatrices dont les algorithmes opéraient sur des nombres avec l'idée d'un ordinateur dont les algorithmes opéraient sur des données complexes. Les structures de données peuvent être utilisées pour représenter des données complexes en modélisant la hiérarchie et les relations.
Nous pourrions représenter un magasin de détail en ligne comme une carte associant chaque article à des détails tels qu'une image, une brève description, le prix et le nombre d'articles en stock. Cette carte facilite l'implémentation de certaines fonctionnalités de vitrine en ligne par rapport à d'autres. Étant donné un article, cette carte facilite la récupération des détails associés à cet article. D'un autre côté, il n'est pas si facile de trier les articles par prix, de trier les articles par popularité ou de rechercher un article par mots-clés dans sa description. Toutes ces fonctionnalités pourraient être implémentées avec des structures de données supplémentaires. Nous pouvons combiner plusieurs structures de données pour implémenter ces fonctionnalités. En informatique, nous utilisons des systèmes de bases de données (voir Chapitre 8 Gestion des données) qui fonctionnent en coulisses dans de nombreuses applications pour gérer ces structures de données et faciliter le stockage à long terme et l'accès à de grandes quantités de données.
Tout comme les calculatrices ont des algorithmes pour calculer des nombres, les ordinateurs ont des algorithmes pour calculer des données complexes. Les structures de données représentent ces données complexes, et les algorithmes agissent sur ces structures de données.