Я думаю, что ваш первый пример немного неоднозначен - узлы как объекты и края как указатели. Вы можете отслеживать их, сохраняя только указатель на некоторый корневой узел, и в этом случае доступ к данному узлу может быть неэффективным (скажем, вам нужен узел 4 - если объект узла не указан, вам может потребоваться его поиск) , В этом случае вы также потеряете часть графика, недоступную для корневого узла. Я думаю, что это тот случай, когда радуга радует, когда он говорит, что сложность времени для доступа к данному узлу равна O (n).
В противном случае вы также можете сохранить массив (или хэш-карту), полный указателей, для каждого узла. Это позволяет O (1) получить доступ к данному узлу, но немного увеличивает объем памяти. Если n - число узлов, а e - число ребер, пространственная сложность этого подхода будет O (n + e).
Сложность пространства для матричного подхода будет по линиям O (n^2) (при условии, что ребра являются однонаправленными). Если ваш график разрежен, у вас будет много пустых ячеек в вашей матрице. Но если ваш график полностью связан (e = n^2), это выгодно отличается от первого подхода. Как говорит RG, у вас также может быть меньше промахов в кеше с этим подходом, если вы выделите матрицу как один кусок памяти, что может привести к следующему множеству ребер вокруг графика быстрее.
Третий подход, пожалуй, наиболее эффективен для большинства случаев - O (e), но сделает поиск всех ребер данного узла задачей O (e). Я не могу придумать случай, когда это было бы очень полезно.
Я бы рассмотрел матрицу, только если граф был очень связным или очень маленьким. Для малосвязанных графиков подход к объекту/указателю или списку ребер будет намного лучше использовать память. Мне любопытно, что, кроме хранения, я забыл. ;) – sarnold
Они также отличаются временной сложностью, матрица O (1), а другие представления могут сильно варьироваться в зависимости от того, что вы ищете. – msw
Я помню, как некоторое время читал статью, описывая аппаратные преимущества реализации графика в виде матрицы над списком указателей. Я не могу много помнить об этом, кроме того, поскольку вы имеете дело с непрерывным блоком памяти, в любой момент времени ваш рабочий набор вполне может быть в кэше L2. Список узлов/указателей, с другой стороны, может быть запущен с помощью памяти, и, вероятно, потребуется выборка, которая не попадает в кеш. Я не уверен, что согласен, но это интересная мысль. – nerraga