Cette réponse ne concerne pas uniquement le C++ puisque tout ce qui est mentionné concerne les structures de données elles-mêmes, indépendamment du langage. Et ma réponse suppose que vous connaissez la structure de base des listes et des matrices d'adjacence.
Mémoire
Si la mémoire est votre principale préoccupation, vous pouvez suivre cette formule pour un graphique simple qui autorise les boucles :
Une matrice d'adjacence occupe n 2 /Espace de 8 octets (un bit par entrée).
Une liste d'adjacence occupe 8e espace, où e est le nombre d'arêtes (ordinateur 32 bits).
Si nous définissons la densité du graphique comme d = e/n 2 (nombre d'arêtes divisé par le nombre maximal d'arêtes), nous pouvons trouver le "point de rupture" où une liste occupe plus de mémoire qu'une matrice :
8e > n 2 /8 quand d > 1/64
Ainsi, avec ces chiffres (toujours spécifiques aux 32 bits), le point d'arrêt se situe à l'endroit suivant 1/64 . Si la densité (e/n 2 ) est supérieure à 1/64, alors a matrice est préférable si vous voulez économiser de la mémoire.
Vous pouvez lire à ce sujet sur le site wikipedia (article sur les matrices d'adjacence) et beaucoup d'autres sites.
Note complémentaire : On peut améliorer l'efficacité spatiale de la matrice d'adjacence en utilisant une table de hachage où les clés sont des paires de sommets (non dirigés uniquement).
Itération et recherche
Les listes d'adjacence sont un moyen compact de représenter uniquement les arêtes existantes. Cependant, cela se fait au prix d'une recherche éventuellement lente d'arêtes spécifiques. Puisque chaque liste est aussi longue que le degré d'un sommet, le temps de recherche le plus défavorable pour vérifier une arête spécifique peut devenir O(n), si la liste n'est pas ordonnée. Cependant, la recherche des voisins d'un sommet devient triviale, et pour un graphe peu dense ou petit, le coût de l'itération à travers les listes d'adjacence peut être négligeable.
Les matrices d'adjacence, quant à elles, utilisent plus d'espace afin de fournir un temps de consultation constant. Puisque chaque entrée possible existe, vous pouvez vérifier l'existence d'un bord en temps constant en utilisant des index. Cependant, la recherche de voisins prend O(n) puisqu'il faut vérifier tous les voisins possibles. L'inconvénient évident en termes d'espace est que pour les graphes épars, beaucoup de remplissage est ajouté. Voir la discussion sur la mémoire ci-dessus pour plus d'informations à ce sujet.
Si vous n'êtes toujours pas sûr de ce que vous devez utiliser : La plupart des problèmes du monde réel produisent des graphes épars et/ou de grande taille, qui sont mieux adaptés aux représentations de listes d'adjacence. Elles peuvent sembler plus difficiles à mettre en œuvre mais je vous assure qu'elles ne le sont pas, et lorsque vous écrivez un BFS ou un DFS et que vous voulez récupérer tous les voisins d'un nœud, elles ne sont qu'à une ligne de code. Cependant, notez que je ne fais pas la promotion des listes d'adjacence en général.
31 votes
La structure que vous utilisez ne dépend pas de la langue mais du problème que vous essayez de résoudre.
1 votes
Je voulais dire pour une utilisation générale comme l'algorithme de Djikstra, je pose cette question parce que je ne sais pas si l'implémentation de la liste liée vaut la peine d'être essayée parce que c'est plus difficile à coder que la matrice d'adjacence.
0 votes
Les listes en C++ sont aussi simples que de taper
std::list
(ou mieux encore,std::vector
).2 votes
@avakar : ou
std::deque
oustd::set
. Cela dépend de la façon dont le graphique évoluera dans le temps et des algorithmes que vous avez l'intention d'exécuter sur celui-ci.1 votes
Lire les détails de académie khan
0 votes
Je trouve cela réponse utile également.