Adjacency is an array with | V | lists, one for each
vertex." u Î V
Adj[u] is the adjacency list for vertex u and points to all vertices v so
that the edge ( u, v ) Î E. If G is a directed
graph, then:
|
å
u Î V |
| Adj [u] | = | E | |
|
If G is an undirected graph, then:
|
å
u Î V |
| Adj [u] | = 2 | E | |
With the adjacency-list representation we have that:
O ( max ( | V |, | E | )) = O ( | V | + | E | )
memory is required. This is as small as we can imagine if G does not
have a special (computable) structure. If G is a weighted graph then for
each f Î E we associate wf. with
the adjacency-list representation we merely store wf in the
Adj[u] corresponding to v where ( u, v ) = f, the edge in question. Many
other graph variants are easily incorporated into the adjacency-lists
representation.
Problem: Given edge ( u, v ) is it in the graph ?
Answer: Must search Adj[u] to see if v is there. If Adj[u] is
really big, this can be searching the whole graph.
Solution: (Memory-speed trade off) Adjacency-Matrix
representation. Assume that the vertices are numbered: 1, 2, ..., | V |.
Associate with G the | V | x | V | matrix [A]ij = aij
so that aij = 1 if ( i, j ) Î E and
0 otherwise. This representation takes O ( | V |2 )
memory whether G is sparse or dense! Clearly: ( u, v ) Î
G ? can be answered in O ( 1 ) time!
If G is an undirected graph, then if ( i, j ) Î Gso
is ( j, i ) thus we have: if aij = 1, aji = 1and
if aij = 0 then aji = 0, so aij = aji
. [AT]ij = aji , AT
is the transpose of A, swapping across a diagonal division of the matrix.
In an undirected graph, A = AT (symmetric) instead of
"1" in A we can use w. If 0 is a valid weight, we must identify
non-edges with another value: "nil".
Note: if aij = 0,1 we can store A in bit form very
efficiently
Symmetric
non-symmetric or asymmetric