Graphs
Graphs are collections of nodes with edges connecting them. In a directed graph, the edges have directions (like an edge might go from to but not from to ), and in an undirected graph, they don't (an edge connecting to also connects to ).
Graphs are called connected if there is a path of edges connecting all nodes. A directed graph with no cycles (no directed paths that can lead in a circle) is called acyclic. A graph is weighted if each edge has an associated weight.
There are two main ways to represent a graph programmatically.
Adjacency-list representation
For a graph , an adjacency-list representation starts with an array of pointers, where is the number of vertices in the graph. Each pointer in the array points to a linked list, where each node in the linked list specifies another vertex in the graph. The presence (or absence) of a node indicates an edge from the node whose adjacency list list it is to the vertex specified by the node.
For example, in the spot in the array corresponds to the edges leaving the vertex . In 's adjacency list, the presence of a node with the value indicates that in our graph, there is an edge from to .
For directed graphs, a node in 's adjacency list specifies an edge from to , which doesn't imply an edge from to .
This adjacency-list schema uses memory, where is the number of vertices and is the number of edges: an array of elements and then total linked list nodes. Iterating over each edge takes time, for the same reason, although since worst-case, there are asymptotically more edges than nodes (in a fully connected graph (the worst-case), there are edges for nodes), we can just say iterating over each node is .
Adjacency-matrix representation
The adjacency-matrix representation for a graph uses a matrix where
This approach requires memory, but is irrespective of the number of edges in the graph. Iterating over each edge takes time.
Comparison
Generally, the adjacency-list approach is better for sparsely connected graphs; where , and the adjacency-matrix approach is better for densely connected graphs where approaches . Also, in the adjacency-list approach, looking for the presence of an edge requires indexing into the array and then searching the linked list (worst case ), whereas the adjacency-matrix approach takes constant time for edge lookup.