Questa risposta non è solo per C ++ poiché tutto quanto menzionato riguarda le strutture di dati stesse, indipendentemente dalla lingua. E, la mia risposta è supporre che tu conosca la struttura di base delle liste di adiacenza e delle matrici.
Memoria
Se la memoria è la tua preoccupazione principale, puoi seguire questa formula per un semplice grafico che consenta loop:
Una matrice di adiacenza occupa n 2 /8 byte di spazio (un bit per voce).
Un elenco di adiacenza occupa 8e spazio, dove e è il numero di spigoli (computer a 32 bit).
Se definiamo la densità del grafico come d = e / n 2 (numero di bordi diviso per il numero massimo di bordi), possiamo trovare il "punto di interruzione" in cui un elenco occupa più memoria di una matrice:
8e> n 2 /8 quando d> 1/64
Quindi con questi numeri (ancora specifici a 32 bit) il breakpoint atterra a 1/64 . Se la densità (e / n 2 ) è maggiore di 1/64, è preferibile una matrice se si desidera risparmiare memoria.
Puoi leggere questo su Wikipedia (articolo sulle matrici di adiacenza) e molti altri siti.
Nota a margine : è possibile migliorare l'efficienza dello spazio della matrice di adiacenza utilizzando una tabella hash in cui i tasti sono coppie di vertici (solo non indirizzati).
Iterazione e ricerca
Gli elenchi di adiacenza sono un modo compatto di rappresentare solo i bordi esistenti. Tuttavia, questo ha un costo per una possibile ricerca lenta di bordi specifici. Poiché ogni elenco è lungo quanto il grado di un vertice, il tempo di ricerca nel caso peggiore del controllo di un bordo specifico può diventare O (n), se l'elenco non è ordinato. Tuttavia, cercare i vicini di un vertice diventa banale e per un grafico scarso o piccolo il costo dell'iterazione attraverso gli elenchi di adiacenza potrebbe essere trascurabile.
Le matrici di adiacenza invece usano più spazio per fornire un tempo di ricerca costante. Poiché esiste ogni possibile voce, è possibile verificare l'esistenza di uno spigolo in tempo costante utilizzando gli indici. Tuttavia, la ricerca del vicino richiede O (n) poiché è necessario controllare tutti i possibili vicini. L'ovvio svantaggio dello spazio è che per i grafici sparsi viene aggiunta molta imbottitura. Vedi la discussione di memoria sopra per ulteriori informazioni al riguardo.
Se non sei ancora sicuro di cosa usare : la maggior parte dei problemi del mondo reale produce grafici sparsi e / o grandi, che sono più adatti per le rappresentazioni dell'elenco di adiacenza. Potrebbero sembrare più difficili da implementare, ma ti assicuro che non lo sono, e quando scrivi un BFS o DFS e vuoi recuperare tutti i vicini di un nodo, sono solo una riga di codice. Tuttavia, tieni presente che non sto promuovendo elenchi di adiacenza in generale.