Acho que seu primeiro exemplo é um pouco ambíguo - nós como objetos e bordas como ponteiros. Você pode acompanhar isso armazenando apenas um ponteiro para algum nó raiz, caso em que acessar um determinado nó pode ser ineficiente (digamos que você queira o nó 4 - se o objeto de nó não for fornecido, talvez seja necessário procurá-lo) . Nesse caso, você também perderia partes do gráfico que não podem ser alcançadas a partir do nó raiz. Acho que é esse o caso que f64 rainbow está assumindo quando diz que a complexidade de tempo para acessar um determinado nó é O (n).
Caso contrário, você também pode manter uma matriz (ou hashmap) cheia de ponteiros para cada nó. Isso permite o acesso O (1) a um determinado nó, mas aumenta um pouco o uso da memória. Se n é o número de nós e e é o número de arestas, a complexidade espacial dessa abordagem seria O (n + e).
A complexidade do espaço para a abordagem da matriz seria ao longo das linhas de O (n ^ 2) (assumindo que as arestas são unidirecionais). Se seu gráfico for esparso, você terá muitas células vazias em sua matriz. Mas se o seu gráfico estiver totalmente conectado (e = n ^ 2), isso se compara favoravelmente com a primeira abordagem. Como RG diz, você também pode ter menos perdas de cache com esta abordagem se alocar a matriz como um pedaço de memória, o que pode tornar mais rápido seguir várias bordas ao redor do gráfico.
A terceira abordagem é provavelmente a mais eficiente em termos de espaço para a maioria dos casos - O (e) - mas tornaria a localização de todas as arestas de um determinado nó uma tarefa O (e). Não consigo pensar em um caso em que isso seria muito útil.