Esta respuesta no es solo para C ++, ya que todo lo mencionado se refiere a las estructuras de datos en sí mismas, independientemente del lenguaje. Y, mi respuesta es asumir que conoces la estructura básica de las listas y matrices de adyacencia.
Memoria
Si la memoria es su principal preocupación, puede seguir esta fórmula para un gráfico simple que permita bucles:
Una matriz de adyacencia ocupa n 2 /8 Superficie byte (un bit por entrada).
Una lista de adyacencia ocupa 8e espacio, donde e es el número de bordes (computadora de 32 bits).
Si definimos la densidad del gráfico como d = e / n 2 (número de aristas dividido por el número máximo de aristas), podemos encontrar el "punto de ruptura" donde una lista ocupa más memoria que una matriz:
8e> n 2 /8 cuando d> 1/64
Entonces, con estos números (aún específicos de 32 bits), el punto de ruptura cae en 1/64 . Si la densidad (e / n 2 ) es mayor que 1/64, entonces es preferible una matriz si desea ahorrar memoria.
Puede leer sobre esto en wikipedia (artículo sobre matrices de adyacencia) y en muchos otros sitios.
Nota al margen : se puede mejorar la eficiencia espacial de la matriz de adyacencia mediante el uso de una tabla hash donde las claves son pares de vértices (solo no dirigidos).
Iteración y búsqueda
Las listas de adyacencia son una forma compacta de representar solo los bordes existentes. Sin embargo, esto tiene el costo de una posible búsqueda lenta de bordes específicos. Dado que cada lista es tan larga como el grado de un vértice, el peor tiempo de búsqueda de un borde específico puede convertirse en O (n), si la lista no está ordenada. Sin embargo, buscar a los vecinos de un vértice se vuelve trivial, y para un gráfico escaso o pequeño, el costo de iterar a través de las listas de adyacencia puede ser insignificante.
Las matrices de adyacencia, por otro lado, usan más espacio para proporcionar un tiempo de búsqueda constante. Dado que existen todas las entradas posibles, puede verificar la existencia de un borde en tiempo constante utilizando índices. Sin embargo, la búsqueda de vecinos toma O (n) ya que debe verificar todos los vecinos posibles. El inconveniente obvio del espacio es que para gráficos dispersos se agrega mucho relleno. Consulte la discusión sobre la memoria anterior para obtener más información al respecto.
Si todavía no está seguro de qué usar : la mayoría de los problemas del mundo real producen gráficos dispersos y / o grandes, que son más adecuados para las representaciones de listas de adyacencia. Puede parecer más difícil de implementar, pero le aseguro que no lo son, y cuando escribe un BFS o DFS y desea buscar a todos los vecinos de un nodo, están a solo una línea de código. Sin embargo, tenga en cuenta que no estoy promocionando listas de adyacencia en general.