Хорошо, если вам важна эффективность использования пространства, тогда лучше всего использовать сжатую структуру данных - но, конечно, это не очень эффективно для доступа или обновления .....
Если ваш граф имеет относительно небольшое количество узлов и достаточно плотный (скажем, существует не менее 5% всех возможных соединений), то вы можете обнаружить, что для создания матрицы смежности более эффективно использовать пространство , чем использовать списки ребер. Для этого потребуется всего один бит на каждое возможное (направленное) соединение и всего n * n бит, если у вас есть n узлов.
В противном случае, если вам нужно использовать соседние ссылки, вы не сможете легко справиться лучше, чем одна ссылка на ссылку, поскольку это минимальное информационное содержимое, которое вам нужно хранить. Если вам нужны обратные ссылки, вам понадобится вдвое больше ссылок.
Есть некоторые трюки, которые вы можете попробовать в дополнение к этому. Например, вы можете попробовать поделиться подмножествами ссылок (если A и B ссылаются на каждый из C, D, E, тогда сохраните список ссылок C, D, E только один раз .....). Однако это довольно быстро станет сложным, и я сомневаюсь, что в большинстве случаев это будет стоить усилий.
Еще одна хитрость - если у вашего графа разумное количество узлов, вы, безусловно, сэкономите место за счет индексации, например, используя 16-битный номер индекса узла, а не полный указатель / ссылку.