Hello! Let‘s Learn About Graphs in Java

A graph models relationships between things. It consists of vertices – which represent entities – connected together by edges – which represent the relations between those entities.

For example, a social network maps people (vertices) and their friendships (edges):

Social Network Graph

Graphs allow us to solve interesting problems about connections and dependencies. This tutorial will explain the common types, properties, structures and algorithms you need to know about graphs in Java…and have some fun along the way!

Graph Basics

Formally, a graph is:

Graph = (Vertices, Edges)

Where:

  • Vertices – Also called nodes. Represent entities/objects
  • Edges – Represent relations between the vertices

For example, cities and routes between them:

City Graph

Some key terms:

  • Path: Sequence of edges between vertices
  • Directed Graph: Edges go one way
  • Undirected Graph: Edges go both ways
  • Weighted Graph: Edges have numeric values

Next let‘s look at variants and properties…

Types of Graphs

There are a few common graph types and properties to know:

Graph Type Description Example
Directed Edges go one direction Web links
Undirected Edges go both directions Friendships
Weighted Edges have numeric values Airline prices
Cyclic Has cycles (arrows that start/end at same vertex) Comment threads
Acyclic No cycles allowed Family trees
Connected All vertices are connected somehow Facebook friends

These categories intersect – you can have a weighted, cyclic, directed graph and so on.

The structure impacts possible algorithms. Cycles allow feedback paths, while acyclic graphs have defined inputs/outputs useful for scheduling. Weights on edges enable computed shortest paths or minimum spanning trees.

First though, we need to represent graphs programmatically…

Graph Representations

There are two common ways to store graphs:

Adjacency Matrix

An adjacency matrix uses a VxV boolean matrix, where V is number of vertices. Each cell indicates if an edge exists between two vertices.

For example, a 5 vertex graph:

A B C D E
A x x x
B x x
C x x
D x
E x x
  • Simple, intuitive
  • Fast edge lookup O(1)
  • But uses more memory (V^2 space)

Adjacency List

The adjacency list format has each vertex store a list of its adjacent vertices.

Adjacency List

  • Saves space on sparse graphs
  • Edge check is slower O(E)
  • Faster to iterate edges

Tradeoffs depend on graph density and operations used.

Up next, graph processing in Java!

Graph Implementation in Java

We‘ll implement a directed weighted graph using adjacency lists in Java:

class Graph {

    private Map<Integer, List<Edge>> adjList = new HashMap<>();

    static class Edge {
        int dest; 
        int weight;

        // Constructor
        Edge(int dest, int weight) {
            this.dest = dest;
            this.weight = weight;    
        }
    }

    public void addEdge(int src, int dest, int weight) {
        // Add edge to source vertex adjacency list 
        adjList.computeIfAbsent(src, x-> new ArrayList());  
        adjList.get(src).add(new Edge(dest, weight)); 
    }

}

This maps vertices to adjacency lists containing destination vertices and weights.

We can add edges with:

Graph g = new Graph();
g.addEdge(0, 1, 5); // 0->1 edge with weight 5

And there we have a graph structure in Java!

Now what can we do with graphs? Turns out, a lot!

Graph Algorithms

Some key things we can compute on graphs include:

  • Pathfinding – Find paths between two vertices
  • Shortest Paths – Optimize routes by edge weights
  • Spanning Trees – Define structure backbone
  • Connectivity – Check if all connected
  • Cycles & Dependencies – Detect feedback loops

This involves graph traversal – systematically visiting vertices of a graph.

Popular ways to traverse graphs:

Depth First Search

  • Start at one vertex and explores as far as possible down each branch before backtracking
  • Uses less memory, explores rapidly
  • Useful for checking connectivity

Depth First Search

DFS in Java:

void dfs(int node, Set<Integer> visited) {
    visited.add(node);  
    // Recurse on adjacent unvisited vertices
    for (Edge e : adjList.get(node)) {
        if (!visited.contains(e.dest)) {
            dfs(e.dest, visited);
        }
    }
}

Breadth First Search

  • Explores all neighbors first before going deeper
  • Finds shortest paths in unweighted graphs
  • Uses more memory with vertex queue

Breadth First Search

And breadth-first in Java:

void bfs(int root) {
    Set<Integer> visited = new HashSet(); 
    Queue<Integer> queue = new LinkedList();   

    visited.add(root);
    queue.add(root);

    while (!queue.isEmpty()) {
        int node = queue.poll();
        for (Edge e : adjList.get(node)) {
            if (!visited.contains(e.dest)) {
                visited.add(e.dest);
                queue.add(e.dest); 
            }
        }
    }
}

Choosing an algorithm depends on the problem and graph traits.

Now let‘s look at real-world uses!

Applications of Graphs

Graphs have tons of practical applications:

  • Networks: Model road systems, computer networks, infrastructure etc. Optimize traffic flows.
  • Recommendations: Build suggestion graphs based on similarity/preferences
  • Shortest Paths: Find fastest routes in mapping apps like Google Maps
  • Scheduling: Resolve task dependencies and order using directed acyclic graphs
  • Machine Learning: Probabilistic models like Bayes Nets or Markov Chains
  • Databases: Store non-tabular linked data with graph databases

And many more uses…

The connections and relations modeled by graphs are everywhere!

Key Takeaways

We covered a lot of ground working with graphs in Java! To recap:

  • Graphs connect vertices via edges
  • Directed/weighted graphs add constraints
  • Adjacency lists efficiently store relations
  • Traversals like DFS & BFS visit vertices
  • Applications span networks, data and more

So in summary:

  • Graphs flexibly represent connections
  • Structure impacts algorithms
  • Implementations optimize space/time tradeoffs
  • Useful both abstractly and practically!

I hope you feel better equipped to leverage graphs for modeling domains and tackling problems. Reach out if you have any other questions!

Read More Topics