Этот ответ предназначен не только для C ++, поскольку все упомянутое касается самих структур данных, независимо от языка. И мой ответ предполагает, что вы знаете базовую структуру списков и матриц смежности.
объем памяти
Если память - ваша главная забота, вы можете следовать этой формуле для простого графика, который допускает циклы:
Матрица смежности занимает п 2 /8 байт пространства (один бит на входе).
Список смежности занимает пространство 8e, где e - количество ребер (32-битный компьютер).
Если мы определим плотность графа как d = e / n 2 (количество ребер, деленное на максимальное количество ребер), мы можем найти «точку останова», где список занимает больше памяти, чем матрица:
8e> п 2 /8 при д> 1/64
Таким образом, с этими числами (по-прежнему 32-битными) точка останова достигает 1/64 . Если плотность (e / n 2 ) больше 1/64, то матрица предпочтительнее, если вы хотите сэкономить память.
Вы можете прочитать об этом в Википедии (статья о матрицах смежности) и на многих других сайтах.
Боковое примечание : можно улучшить пространственную эффективность матрицы смежности, используя хеш-таблицу, в которой ключи представляют собой пары вершин (только неориентированные).
Итерация и поиск
Списки смежности - это компактный способ представления только существующих ребер. Однако это происходит за счет возможного медленного поиска определенных ребер. Поскольку каждый список имеет длину, равную степени вершины, в худшем случае время поиска для проверки конкретного ребра может стать O (n), если список неупорядочен. Однако поиск соседей вершины становится тривиальным, а для разреженного или маленького графа стоимость итерации по спискам смежности может быть незначительной.
С другой стороны, матрицы смежности используют больше места для обеспечения постоянного времени поиска. Поскольку существует каждая возможная запись, вы можете проверить наличие края в постоянное время с помощью индексов. Однако поиск соседей занимает O (n), поскольку вам нужно проверить всех возможных соседей. Очевидный недостаток места в том, что для разреженных графов добавляется много отступов. См. Обсуждение памяти выше для получения дополнительной информации об этом.
Если вы все еще не уверены, что использовать : большинство реальных проблем создают разреженные и / или большие графы, которые лучше подходят для представлений списков смежности. Может показаться, что их сложнее реализовать, но я уверяю вас, что это не так, и когда вы пишете BFS или DFS и хотите получить всех соседей узла, они находятся всего в одной строке кода. Однако обратите внимание, что я не продвигаю списки смежности в целом.