- 1. Apa itu Graph?
- 2. Terminologi Graph
- 3. Representasi Graph
- 4. Implementasi Graph
- 5. Operasi Dasar pada Graph
- 6. Aplikasi Graph di Dunia Nyata
- 7. Latihan Praktikum
- 8. Soal Latihan di Kelas
- Referensi
Graph adalah struktur data non-linear yang terdiri dari:
- Vertex (Node): Titik atau simpul dalam graph
- Edge (Arc): Garis yang menghubungkan dua vertex
Secara matematis, graph G didefinisikan sebagai:
G = (V, E)
dimana:
- V = himpunan vertex (simpul)
- E = himpunan edge (sisi) yang menghubungkan pasangan vertex
Contoh:
Graph Pertemanan:
Alice ─────── Bob
│ / │
│ / │
│ / │
Carol ─────── Dave
V = {Alice, Bob, Carol, Dave}
E = {(Alice, Bob), (Alice, Carol), (Bob, Carol), (Bob, Dave), (Carol, Dave)}
| Aspek | Tree | Graph |
|---|---|---|
| Struktur | Hierarkis (parent-child) | Non-hierarkis |
| Root | Ada satu root | Tidak ada konsep root |
| Cycle | Tidak ada cycle | Bisa ada cycle |
| Edge | n-1 edge untuk n node | Bebas, bisa 0 sampai n(n-1)/2 |
| Konektivitas | Selalu connected | Bisa connected atau disconnected |
| Path | Hanya satu path antar node | Bisa ada banyak path |
Tree: Graph:
A A ─── B
/ \ │ \ │
B C │ \ │
/ \ C ─── D
D E
Tidak ada cycle Bisa ada cycle (A-B-D-C-A)
Vertex (Node/Simpul)
Vertex mewakili entitas:
○ A ○ B ○ C
Setiap vertex bisa memiliki label dan data
Edge (Sisi/Arc)
Edge menghubungkan dua vertex:
Undirected Edge: Directed Edge:
A ───── B A ─────> B
(bisa dua arah) (satu arah saja)
Adjacent (Bertetangga)
Dua vertex disebut adjacent jika terhubung langsung oleh edge.
A ─── B ─── C
A dan B: adjacent
B dan C: adjacent
A dan C: TIDAK adjacent (tidak terhubung langsung)
Degree (Derajat)
Degree = jumlah edge yang terhubung ke vertex
B
│
A ─── C ─── D
│
E
Degree(A) = 1
Degree(C) = 4
Degree(B) = 1
Untuk Directed Graph:
- In-degree: Jumlah edge yang masuk ke vertex
- Out-degree: Jumlah edge yang keluar dari vertex
A ───> B ───> C
│ ↑
│ │
↓ │
D ─────┘
In-degree(B) = 2 (dari A dan D)
Out-degree(B) = 1 (ke C)
Undirected Graph (Graf Tak Berarah)
Edge tidak memiliki arah, bisa dilalui dua arah.
A ───── B
│ │
│ │
C ───── D
Jika ada edge (A, B), maka bisa dari A ke B dan B ke A.
Directed Graph (Graf Berarah / Digraph)
Edge memiliki arah, hanya bisa dilalui satu arah.
A ────> B
│ │
↓ ↓
C <──── D
Edge (A, B) berarti hanya bisa dari A ke B, TIDAK bisa dari B ke A.
Unweighted Graph (Graf Tanpa Bobot)
Setiap edge dianggap sama (bobot = 1).
A ───── B
│ │
│ │
C ───── D
Weighted Graph (Graf Berbobot)
Setiap edge memiliki bobot/nilai.
A ──5── B
│ │
3 2
│ │
C ──4── D
Bobot bisa merepresentasikan: jarak, waktu, biaya, dll.
Connected Graph
Setiap pasangan vertex terhubung (ada path).
A ───── B
│ │
│ │
C ───── D
Semua vertex bisa dijangkau dari vertex manapun.
Disconnected Graph
Ada vertex yang tidak terhubung.
A ───── B E ───── F
│ │
│ │
C G
Komponen 1: {A, B, C}
Komponen 2: {E, F, G}
Strongly Connected (untuk Directed Graph)
Setiap pasangan vertex terhubung DUA ARAH.
A ────> B
↑ │
│ ↓
D <──── C
Dari vertex manapun, bisa mencapai vertex lainnya.
Weakly Connected (untuk Directed Graph)
Connected jika arah edge diabaikan.
A ────> B
│
↓
D C
Weakly connected (jika arah diabaikan, semuanya terhubung)
NOT strongly connected (tidak bisa dari C ke A)
Complete Graph (K_n)
Setiap vertex terhubung ke semua vertex lainnya.
K4 (Complete graph dengan 4 vertex):
A ─────── B
│ ╲ ╱ │
│ ╲ ╱ │
│ ╱ ╲ │
│ ╱ ╲ │
C ─────── D
Jumlah edge = n(n-1)/2 = 4×3/2 = 6
Bipartite Graph
Vertex bisa dibagi menjadi 2 grup, edge hanya menghubungkan antar grup.
Grup 1: {A, B, C} Grup 2: {X, Y}
A ──────── X
│ ╲ ╱
│ ╲ ╱
B ─────── Y
│
C ────────┘
Tidak ada edge antara vertex dalam grup yang sama.
Contoh: Matching mahasiswa dengan mata kuliah
Cyclic vs Acyclic Graph
Cyclic (ada cycle): Acyclic (DAG - Directed Acyclic Graph):
A ────> B A ────> B
↑ │ │
│ ↓ ↓
D <──── C D <──── C
│
Ada cycle: A→B→C→D→A ↓
E
Tidak ada cycle, sering digunakan untuk
task scheduling, dependency management
Path (Jalur)
Urutan vertex yang terhubung oleh edge.
A ─── B ─── C ─── D ─── E
Path dari A ke E: A → B → C → D → E
Panjang path = 4 (jumlah edge)
Simple Path
Path tanpa vertex yang berulang.
A → B → C → D ← Simple path (tidak ada vertex berulang)
A → B → C → B → D ← BUKAN simple path (B muncul 2 kali)
Cycle (Siklus)
Path yang dimulai dan berakhir di vertex yang sama.
A ─── B
│ │
│ │
D ─── C
Cycle: A → B → C → D → A
Self-Loop
Edge yang menghubungkan vertex ke dirinya sendiri.
A ─── B
│ ↺ (self-loop pada B)
│
C
Multiple Edges (Multi-graph)
Lebih dari satu edge antara pasangan vertex yang sama.
A ═══ B
═══
Dua edge berbeda antara A dan B.
Adjacency Matrix adalah matriks 2D berukuran V×V dimana:
matrix[i][j] = 1jika ada edge dari vertex i ke vertex jmatrix[i][j] = 0jika tidak ada edge
Contoh Undirected Graph:
Graph: Adjacency Matrix:
0 ─── 1 0 1 2 3
│ ╲ │ 0 [ 0 1 1 1 ]
│ ╲ │ 1 [ 1 0 1 0 ]
2 ─── 3 2 [ 1 1 0 1 ]
3 [ 1 0 1 0 ]
Matriks simetris karena undirected (edge dua arah)
Contoh Directed Graph:
Graph: Adjacency Matrix:
0 ───> 1 0 1 2 3
│ │ 0 [ 0 1 1 1 ]
↓ ↓ 1 [ 0 0 1 0 ]
2 <─── 3 2 [ 0 0 0 0 ]
3 [ 0 0 1 0 ]
Matriks TIDAK simetris karena directed (edge satu arah)
Contoh Weighted Graph:
Graph: Adjacency Matrix (dengan bobot):
0 ─5─ 1 0 1 2 3
│ │ 0 [ 0 5 3 0 ]
3 2 1 [ 5 0 2 0 ]
│ │ 2 [ 3 2 0 4 ]
2 ─4─ 3 3 [ 0 0 4 0 ]
0 = tidak ada edge
Nilai lain = bobot edge
Kelebihan Adjacency Matrix:
- Cek edge O(1): langsung akses
matrix[i][j] - Simple untuk graph dense (banyak edge)
Kekurangan Adjacency Matrix:
- Space O(V²) meskipun edge sedikit
- Iterasi neighbor O(V)
- Tidak efisien untuk graph sparse (sedikit edge)
Adjacency List menyimpan daftar neighbor untuk setiap vertex.
Contoh Undirected Graph:
Graph: Adjacency List:
0 ─── 1 0 → [1, 2, 3]
│ ╲ │ 1 → [0, 2]
│ ╲ │ 2 → [0, 1, 3]
2 ─── 3 3 → [0, 2]
Contoh Directed Graph:
Graph: Adjacency List:
0 ───> 1 0 → [1, 2, 3]
│ │ 1 → [2]
↓ ↓ 2 → []
2 <─── 3 3 → [2]
Contoh Weighted Graph:
Graph: Adjacency List (dengan bobot):
0 ─5─ 1 0 → [(1,5), (2,3)]
│ │ 1 → [(0,5), (2,2)]
3 2 2 → [(0,3), (1,2), (3,4)]
│ │ 3 → [(2,4)]
2 ─4─ 3
Format: (vertex tujuan, bobot)
Kelebihan Adjacency List:
- Space O(V + E), efisien untuk sparse graph
- Iterasi neighbor O(degree)
- Mudah menambah vertex baru
Kekurangan Adjacency List:
- Cek edge O(degree), lebih lambat dari matrix
- Lebih kompleks untuk graph dense
Edge List menyimpan semua edge sebagai daftar pasangan vertex.
Graph: Edge List:
0 ─── 1 [(0,1), (0,2), (0,3), (1,2), (2,3)]
│ ╲ │
│ ╲ │ Untuk weighted:
2 ─── 3 [(0,1,5), (0,2,3), (1,2,2), (2,3,4)]
Format: (source, destination, weight)
Kelebihan Edge List:
- Space O(E), paling efisien untuk graph sangat sparse
- Mudah untuk iterasi semua edge
- Cocok untuk algoritma seperti Kruskal
Kekurangan Edge List:
- Cek edge O(E)
- Cari neighbor O(E)
| Operasi | Adjacency Matrix | Adjacency List | Edge List |
|---|---|---|---|
| Space | O(V²) | O(V + E) | O(E) |
| Add Vertex | O(V²) | O(1) | O(1) |
| Add Edge | O(1) | O(1) | O(1) |
| Remove Edge | O(1) | O(degree) | O(E) |
| Check Edge | O(1) | O(degree) | O(E) |
| Get Neighbors | O(V) | O(degree) | O(E) |
| Get All Edges | O(V²) | O(V + E) | O(E) |
Kapan Menggunakan Apa?
| Representasi | Gunakan Ketika |
|---|---|
| Adjacency Matrix | Graph dense (banyak edge), sering cek keberadaan edge |
| Adjacency List | Graph sparse (sedikit edge), sering iterasi neighbor |
| Edge List | Perlu iterasi semua edge (Kruskal), graph sangat sparse |
Rumus Menentukan Dense vs Sparse:
Maksimum edge untuk undirected graph: V(V-1)/2
Maksimum edge untuk directed graph: V(V-1)
Sparse: E << V²
Dense: E mendekati V²
// File: GraphMatrix.java
public class GraphMatrix {
private int[][] matrix;
private int numVertices;
private boolean isDirected;
public GraphMatrix(int numVertices, boolean isDirected) {
this.numVertices = numVertices;
this.isDirected = isDirected;
this.matrix = new int[numVertices][numVertices];
}
// Menambah edge
public void addEdge(int source, int destination) {
validateVertex(source);
validateVertex(destination);
matrix[source][destination] = 1;
// Jika undirected, tambahkan juga sebaliknya
if (!isDirected) {
matrix[destination][source] = 1;
}
}
// Menghapus edge
public void removeEdge(int source, int destination) {
validateVertex(source);
validateVertex(destination);
matrix[source][destination] = 0;
if (!isDirected) {
matrix[destination][source] = 0;
}
}
// Cek apakah ada edge
public boolean hasEdge(int source, int destination) {
validateVertex(source);
validateVertex(destination);
return matrix[source][destination] == 1;
}
// Mendapatkan semua neighbor dari vertex
public int[] getNeighbors(int vertex) {
validateVertex(vertex);
// Hitung jumlah neighbor
int count = 0;
for (int i = 0; i < numVertices; i++) {
if (matrix[vertex][i] == 1) count++;
}
// Buat array neighbor
int[] neighbors = new int[count];
int index = 0;
for (int i = 0; i < numVertices; i++) {
if (matrix[vertex][i] == 1) {
neighbors[index++] = i;
}
}
return neighbors;
}
// Mendapatkan degree vertex
public int getDegree(int vertex) {
validateVertex(vertex);
int degree = 0;
for (int i = 0; i < numVertices; i++) {
if (matrix[vertex][i] == 1) degree++;
}
return degree;
}
// Untuk directed graph: in-degree
public int getInDegree(int vertex) {
validateVertex(vertex);
if (!isDirected) {
throw new UnsupportedOperationException("In-degree hanya untuk directed graph!");
}
int inDegree = 0;
for (int i = 0; i < numVertices; i++) {
if (matrix[i][vertex] == 1) inDegree++;
}
return inDegree;
}
// Untuk directed graph: out-degree
public int getOutDegree(int vertex) {
validateVertex(vertex);
if (!isDirected) {
throw new UnsupportedOperationException("Out-degree hanya untuk directed graph!");
}
return getDegree(vertex);
}
// Validasi vertex
private void validateVertex(int vertex) {
if (vertex < 0 || vertex >= numVertices) {
throw new IllegalArgumentException("Vertex " + vertex + " tidak valid!");
}
}
// Menampilkan adjacency matrix
public void display() {
System.out.println("\nAdjacency Matrix:");
System.out.print(" ");
for (int i = 0; i < numVertices; i++) {
System.out.print(i + " ");
}
System.out.println();
for (int i = 0; i < numVertices; i++) {
System.out.print(i + " ");
for (int j = 0; j < numVertices; j++) {
System.out.print(matrix[i][j] + " ");
}
System.out.println();
}
}
// Menampilkan graph secara visual
public void displayGraph() {
System.out.println("\nGraph (Adjacency List format):");
for (int i = 0; i < numVertices; i++) {
System.out.print(i + " → ");
boolean first = true;
for (int j = 0; j < numVertices; j++) {
if (matrix[i][j] == 1) {
if (!first) System.out.print(", ");
System.out.print(j);
first = false;
}
}
System.out.println();
}
}
public int getNumVertices() {
return numVertices;
}
public static void main(String[] args) {
System.out.println("=== GRAPH DENGAN ADJACENCY MATRIX ===\n");
// Undirected Graph
System.out.println("--- Undirected Graph ---");
GraphMatrix undirected = new GraphMatrix(5, false);
undirected.addEdge(0, 1);
undirected.addEdge(0, 2);
undirected.addEdge(1, 2);
undirected.addEdge(1, 3);
undirected.addEdge(2, 4);
undirected.addEdge(3, 4);
undirected.display();
undirected.displayGraph();
System.out.println("\nDegree of vertex 1: " + undirected.getDegree(1));
System.out.println("Has edge (1,3)? " + undirected.hasEdge(1, 3));
System.out.println("Has edge (0,4)? " + undirected.hasEdge(0, 4));
// Directed Graph
System.out.println("\n--- Directed Graph ---");
GraphMatrix directed = new GraphMatrix(4, true);
directed.addEdge(0, 1);
directed.addEdge(0, 2);
directed.addEdge(1, 2);
directed.addEdge(2, 3);
directed.addEdge(3, 0);
directed.display();
directed.displayGraph();
System.out.println("\nIn-degree of vertex 2: " + directed.getInDegree(2));
System.out.println("Out-degree of vertex 0: " + directed.getOutDegree(0));
}
}Output:
=== GRAPH DENGAN ADJACENCY MATRIX ===
--- Undirected Graph ---
Adjacency Matrix:
0 1 2 3 4
0 0 1 1 0 0
1 1 0 1 1 0
2 1 1 0 0 1
3 0 1 0 0 1
4 0 0 1 1 0
Graph (Adjacency List format):
0 → 1, 2
1 → 0, 2, 3
2 → 0, 1, 4
3 → 1, 4
4 → 2, 3
Degree of vertex 1: 3
Has edge (1,3)? true
Has edge (0,4)? false
--- Directed Graph ---
Adjacency Matrix:
0 1 2 3
0 0 1 1 0
1 0 0 1 0
2 0 0 0 1
3 1 0 0 0
Graph (Adjacency List format):
0 → 1, 2
1 → 2
2 → 3
3 → 0
In-degree of vertex 2: 2
Out-degree of vertex 0: 2
// File: GraphList.java
import java.util.*;
public class GraphList {
private Map<Integer, List<Integer>> adjacencyList;
private boolean isDirected;
public GraphList(boolean isDirected) {
this.adjacencyList = new HashMap<>();
this.isDirected = isDirected;
}
// Menambah vertex
public void addVertex(int vertex) {
adjacencyList.putIfAbsent(vertex, new ArrayList<>());
}
// Menambah edge
public void addEdge(int source, int destination) {
// Pastikan kedua vertex ada
addVertex(source);
addVertex(destination);
// Tambah edge
adjacencyList.get(source).add(destination);
// Jika undirected, tambahkan sebaliknya
if (!isDirected) {
adjacencyList.get(destination).add(source);
}
}
// Menghapus edge
public void removeEdge(int source, int destination) {
List<Integer> sourceList = adjacencyList.get(source);
List<Integer> destList = adjacencyList.get(destination);
if (sourceList != null) {
sourceList.remove(Integer.valueOf(destination));
}
if (!isDirected && destList != null) {
destList.remove(Integer.valueOf(source));
}
}
// Menghapus vertex
public void removeVertex(int vertex) {
// Hapus semua edge yang mengarah ke vertex ini
adjacencyList.values().forEach(list -> list.remove(Integer.valueOf(vertex)));
// Hapus vertex dari list
adjacencyList.remove(vertex);
}
// Cek apakah ada edge
public boolean hasEdge(int source, int destination) {
List<Integer> neighbors = adjacencyList.get(source);
return neighbors != null && neighbors.contains(destination);
}
// Mendapatkan neighbor
public List<Integer> getNeighbors(int vertex) {
return adjacencyList.getOrDefault(vertex, new ArrayList<>());
}
// Mendapatkan degree
public int getDegree(int vertex) {
List<Integer> neighbors = adjacencyList.get(vertex);
return neighbors != null ? neighbors.size() : 0;
}
// In-degree untuk directed graph
public int getInDegree(int vertex) {
if (!isDirected) {
throw new UnsupportedOperationException("In-degree hanya untuk directed graph!");
}
int inDegree = 0;
for (List<Integer> neighbors : adjacencyList.values()) {
if (neighbors.contains(vertex)) {
inDegree++;
}
}
return inDegree;
}
// Out-degree untuk directed graph
public int getOutDegree(int vertex) {
if (!isDirected) {
throw new UnsupportedOperationException("Out-degree hanya untuk directed graph!");
}
return getDegree(vertex);
}
// Mendapatkan semua vertex
public Set<Integer> getVertices() {
return adjacencyList.keySet();
}
// Mendapatkan jumlah vertex
public int getNumVertices() {
return adjacencyList.size();
}
// Mendapatkan jumlah edge
public int getNumEdges() {
int totalEdges = 0;
for (List<Integer> neighbors : adjacencyList.values()) {
totalEdges += neighbors.size();
}
// Untuk undirected graph, setiap edge dihitung 2 kali
return isDirected ? totalEdges : totalEdges / 2;
}
// Menampilkan graph
public void display() {
System.out.println("\nGraph (Adjacency List):");
for (int vertex : adjacencyList.keySet()) {
System.out.print(vertex + " → ");
List<Integer> neighbors = adjacencyList.get(vertex);
if (neighbors.isEmpty()) {
System.out.println("(no neighbors)");
} else {
System.out.println(neighbors);
}
}
}
public static void main(String[] args) {
System.out.println("=== GRAPH DENGAN ADJACENCY LIST ===\n");
// Undirected Graph
System.out.println("--- Undirected Graph ---");
GraphList undirected = new GraphList(false);
undirected.addEdge(0, 1);
undirected.addEdge(0, 2);
undirected.addEdge(1, 2);
undirected.addEdge(1, 3);
undirected.addEdge(2, 4);
undirected.addEdge(3, 4);
undirected.display();
System.out.println("\nVertices: " + undirected.getVertices());
System.out.println("Number of vertices: " + undirected.getNumVertices());
System.out.println("Number of edges: " + undirected.getNumEdges());
System.out.println("Degree of vertex 1: " + undirected.getDegree(1));
System.out.println("Neighbors of vertex 2: " + undirected.getNeighbors(2));
// Directed Graph
System.out.println("\n--- Directed Graph ---");
GraphList directed = new GraphList(true);
directed.addEdge(0, 1);
directed.addEdge(0, 2);
directed.addEdge(1, 2);
directed.addEdge(2, 3);
directed.addEdge(3, 0);
directed.display();
System.out.println("\nIn-degree of vertex 2: " + directed.getInDegree(2));
System.out.println("Out-degree of vertex 0: " + directed.getOutDegree(0));
// Menghapus edge
System.out.println("\n--- Setelah removeEdge(0, 1) ---");
directed.removeEdge(0, 1);
directed.display();
// Menambah vertex terpisah
System.out.println("\n--- Setelah addVertex(5) ---");
directed.addVertex(5);
directed.display();
}
}Output:
=== GRAPH DENGAN ADJACENCY LIST ===
--- Undirected Graph ---
Graph (Adjacency List):
0 → [1, 2]
1 → [0, 2, 3]
2 → [0, 1, 4]
3 → [1, 4]
4 → [2, 3]
Vertices: [0, 1, 2, 3, 4]
Number of vertices: 5
Number of edges: 6
Degree of vertex 1: 3
Neighbors of vertex 2: [0, 1, 4]
--- Directed Graph ---
Graph (Adjacency List):
0 → [1, 2]
1 → [2]
2 → [3]
3 → [0]
In-degree of vertex 2: 2
Out-degree of vertex 0: 2
--- Setelah removeEdge(0, 1) ---
Graph (Adjacency List):
0 → [2]
1 → [2]
2 → [3]
3 → [0]
--- Setelah addVertex(5) ---
Graph (Adjacency List):
0 → [2]
1 → [2]
2 → [3]
3 → [0]
5 → (no neighbors)
// File: WeightedGraph.java
import java.util.*;
class Edge implements Comparable<Edge> {
int source;
int destination;
int weight;
public Edge(int source, int destination, int weight) {
this.source = source;
this.destination = destination;
this.weight = weight;
}
@Override
public int compareTo(Edge other) {
return Integer.compare(this.weight, other.weight);
}
@Override
public String toString() {
return "(" + source + " → " + destination + ", w=" + weight + ")";
}
}
public class WeightedGraph {
private Map<Integer, List<Edge>> adjacencyList;
private boolean isDirected;
public WeightedGraph(boolean isDirected) {
this.adjacencyList = new HashMap<>();
this.isDirected = isDirected;
}
public void addVertex(int vertex) {
adjacencyList.putIfAbsent(vertex, new ArrayList<>());
}
public void addEdge(int source, int destination, int weight) {
addVertex(source);
addVertex(destination);
adjacencyList.get(source).add(new Edge(source, destination, weight));
if (!isDirected) {
adjacencyList.get(destination).add(new Edge(destination, source, weight));
}
}
public void removeEdge(int source, int destination) {
List<Edge> sourceEdges = adjacencyList.get(source);
if (sourceEdges != null) {
sourceEdges.removeIf(edge -> edge.destination == destination);
}
if (!isDirected) {
List<Edge> destEdges = adjacencyList.get(destination);
if (destEdges != null) {
destEdges.removeIf(edge -> edge.destination == source);
}
}
}
public Integer getWeight(int source, int destination) {
List<Edge> edges = adjacencyList.get(source);
if (edges != null) {
for (Edge edge : edges) {
if (edge.destination == destination) {
return edge.weight;
}
}
}
return null; // Edge tidak ditemukan
}
public List<Edge> getEdges(int vertex) {
return adjacencyList.getOrDefault(vertex, new ArrayList<>());
}
public List<Edge> getAllEdges() {
List<Edge> allEdges = new ArrayList<>();
Set<String> seen = new HashSet<>();
for (int vertex : adjacencyList.keySet()) {
for (Edge edge : adjacencyList.get(vertex)) {
String key = Math.min(edge.source, edge.destination) + "-" +
Math.max(edge.source, edge.destination);
if (isDirected || !seen.contains(key)) {
allEdges.add(edge);
seen.add(key);
}
}
}
return allEdges;
}
public Set<Integer> getVertices() {
return adjacencyList.keySet();
}
public int getNumVertices() {
return adjacencyList.size();
}
public void display() {
System.out.println("\nWeighted Graph (Adjacency List):");
for (int vertex : adjacencyList.keySet()) {
System.out.print(vertex + " → ");
List<Edge> edges = adjacencyList.get(vertex);
if (edges.isEmpty()) {
System.out.println("(no edges)");
} else {
List<String> edgeStrings = new ArrayList<>();
for (Edge edge : edges) {
edgeStrings.add(edge.destination + "(w=" + edge.weight + ")");
}
System.out.println(String.join(", ", edgeStrings));
}
}
}
// Display sebagai adjacency matrix
public void displayMatrix() {
List<Integer> vertices = new ArrayList<>(adjacencyList.keySet());
Collections.sort(vertices);
int n = vertices.size();
System.out.println("\nWeighted Adjacency Matrix:");
System.out.print(" ");
for (int v : vertices) {
System.out.printf("%4d", v);
}
System.out.println();
for (int i : vertices) {
System.out.printf("%4d", i);
for (int j : vertices) {
Integer weight = getWeight(i, j);
if (weight == null) {
System.out.print(" ∞");
} else {
System.out.printf("%4d", weight);
}
}
System.out.println();
}
}
public static void main(String[] args) {
System.out.println("=== WEIGHTED GRAPH ===\n");
// Undirected Weighted Graph
System.out.println("--- Undirected Weighted Graph ---");
WeightedGraph graph = new WeightedGraph(false);
// Contoh: Jarak antar kota
graph.addEdge(0, 1, 4); // Kota 0 ke Kota 1: 4 km
graph.addEdge(0, 2, 2); // Kota 0 ke Kota 2: 2 km
graph.addEdge(1, 2, 1); // Kota 1 ke Kota 2: 1 km
graph.addEdge(1, 3, 5); // Kota 1 ke Kota 3: 5 km
graph.addEdge(2, 3, 8); // Kota 2 ke Kota 3: 8 km
graph.addEdge(2, 4, 10); // Kota 2 ke Kota 4: 10 km
graph.addEdge(3, 4, 2); // Kota 3 ke Kota 4: 2 km
graph.display();
graph.displayMatrix();
System.out.println("\nAll edges:");
for (Edge edge : graph.getAllEdges()) {
System.out.println(" " + edge);
}
System.out.println("\nWeight from 1 to 3: " + graph.getWeight(1, 3));
System.out.println("Weight from 0 to 4: " + graph.getWeight(0, 4)); // tidak ada edge langsung
// Directed Weighted Graph
System.out.println("\n--- Directed Weighted Graph ---");
WeightedGraph dirGraph = new WeightedGraph(true);
dirGraph.addEdge(0, 1, 10);
dirGraph.addEdge(0, 2, 3);
dirGraph.addEdge(1, 2, 1);
dirGraph.addEdge(2, 1, 4);
dirGraph.addEdge(2, 3, 2);
dirGraph.display();
dirGraph.displayMatrix();
}
}Output:
=== WEIGHTED GRAPH ===
--- Undirected Weighted Graph ---
Weighted Graph (Adjacency List):
0 → 1(w=4), 2(w=2)
1 → 0(w=4), 2(w=1), 3(w=5)
2 → 0(w=2), 1(w=1), 3(w=8), 4(w=10)
3 → 1(w=5), 2(w=8), 4(w=2)
4 → 2(w=10), 3(w=2)
Weighted Adjacency Matrix:
0 1 2 3 4
0 ∞ 4 2 ∞ ∞
1 4 ∞ 1 5 ∞
2 2 1 ∞ 8 10
3 ∞ 5 8 ∞ 2
4 ∞ ∞ 10 2 ∞
All edges:
(0 → 1, w=4)
(0 → 2, w=2)
(1 → 2, w=1)
(1 → 3, w=5)
(2 → 3, w=8)
(2 → 4, w=10)
(3 → 4, w=2)
Weight from 1 to 3: 5
Weight from 0 to 4: null
--- Directed Weighted Graph ---
Weighted Graph (Adjacency List):
0 → 1(w=10), 2(w=3)
1 → 2(w=1)
2 → 1(w=4), 3(w=2)
3 → (no edges)
Weighted Adjacency Matrix:
0 1 2 3
0 ∞ 10 3 ∞
1 ∞ ∞ 1 ∞
2 ∞ 4 ∞ 2
3 ∞ ∞ ∞ ∞
| Operasi | Deskripsi | Kompleksitas (Matrix) | Kompleksitas (List) |
|---|---|---|---|
addVertex(v) |
Menambah vertex baru | O(V²) | O(1) |
addEdge(u, v) |
Menambah edge antara u dan v | O(1) | O(1) |
removeVertex(v) |
Menghapus vertex dan semua edge-nya | O(V²) | O(V + E) |
removeEdge(u, v) |
Menghapus edge antara u dan v | O(1) | O(degree) |
hasEdge(u, v) |
Cek apakah ada edge | O(1) | O(degree) |
getNeighbors(v) |
Mendapatkan semua neighbor | O(V) | O(degree) |
getDegree(v) |
Mendapatkan degree vertex | O(V) | O(1) atau O(degree) |
getNumVertices() |
Jumlah vertex | O(1) | O(1) |
getNumEdges() |
Jumlah edge | O(V²) | O(V + E) |
Graph Pertemanan Facebook/Instagram:
Vertex = User
Edge = Pertemanan/Following
Alice ─────── Bob
│ ╲ ╱ │
│ ╲ ╱ │
│ ╳ │
│ ╱ ╲ │
│ ╱ ╲ │
Carol ────── Dave
Operasi yang sering dilakukan:
- Mencari teman dari teman (BFS dengan depth terbatas)
- Rekomendasi teman (mutual friends)
- Deteksi komunitas (clustering)
Vertex = Lokasi/Persimpangan
Edge = Jalan (weighted dengan jarak/waktu)
[Rumah] ──5km── [Kantor]
│ │
3km 2km
│ │
[Mall] ───4km── [Resto]
Operasi:
- Shortest path (Dijkstra, A*)
- Alternatif rute
- Traffic estimation
Vertex = Router/Server
Edge = Koneksi (weighted dengan bandwidth/latency)
[Server A] ───── [Router 1] ───── [Server B]
│ │
│ │
[Router 2] ─────────┘
│
[Client]
Operasi:
- Routing packets (shortest path)
- Load balancing
- Network topology analysis
Graph Dependensi Package/Module:
[App] ──────> [React]
│ │
│ ↓
└────> [Webpack] ──> [Node.js]
│
↓
[Babel]
DAG (Directed Acyclic Graph) untuk:
- Build order (topological sort)
- Mendeteksi circular dependency
- Version resolution
Bipartite Graph:
Users: {Alice, Bob, Carol}
Products: {Laptop, Phone, Headphone}
Alice ──────── Laptop
│ ╲ ╱
│ ╲ ╱
│ ╲╱
Bob ──────── Phone
│ ╱
│ ╱
Carol ───── Headphone
Jika Alice dan Bob sama-sama beli Laptop dan Phone,
dan Bob juga beli Headphone, maka Headphone bisa
direkomendasikan ke Alice.
| Domain | Vertex | Edge | Contoh Operasi |
|---|---|---|---|
| Airline | Bandara | Rute Penerbangan | Shortest flight path |
| Biology | Protein | Interaksi | Protein network analysis |
| Games | State | Move | Game tree, pathfinding |
| Compiler | Statement | Data flow | Optimization |
| Web | Page | Hyperlink | PageRank |
Modifikasi GraphList agar bisa menggunakan String sebagai vertex, bukan hanya integer. Contoh penggunaan:
GraphList<String> graph = new GraphList<>(false);
graph.addEdge("Jakarta", "Bandung");
graph.addEdge("Jakarta", "Surabaya");Tambahkan method pada GraphList:
hasSelfLoop(int vertex): mengembalikan true jika vertex memiliki self-loophasMultipleEdges(int u, int v): mengembalikan true jika ada lebih dari satu edge antara u dan v
Implementasikan method transpose() pada directed graph yang membalik arah semua edge.
Original: Transpose:
A ───> B A <─── B
│ │
↓ ↓
C C
Implementasikan method static GraphList createCompleteGraph(int n) yang membuat complete graph dengan n vertex.
Diberikan graph berikut:
A ───── B ───── C
│ │ ╱ │
│ │ ╱ │
D ───── E ───── F
│
G
a) Sebutkan semua vertex yang adjacent dengan E
b) Hitung degree dari setiap vertex
c) Apakah graph ini connected? Jelaskan!
d) Sebutkan semua simple path dari A ke F
e) Apakah graph ini memiliki cycle? Jika ya, sebutkan satu cycle!
Diberikan directed weighted graph:
A ──3──> B
│ │
5 2
│ │
↓ ↓
C <──4── D ──1──> E
a) Gambarkan Adjacency Matrix untuk graph ini
b) Tuliskan Adjacency List untuk graph ini
c) Tuliskan Edge List untuk graph ini
d) Jika ada 100 vertex dan 150 edge, representasi mana yang lebih efisien dari segi memory? Jelaskan perhitungannya!
Implementasikan class BipartiteGraph dengan method:
addLeftVertex(int v): menambah vertex ke grup kiriaddRightVertex(int v): menambah vertex ke grup kananaddEdge(int left, int right): menambah edge (hanya boleh antara grup kiri dan kanan)isValidBipartite(): memvalidasi bahwa tidak ada edge dalam satu grup
Jelaskan dengan singkat:
a) Mengapa graph social network biasanya direpresentasikan dengan adjacency list, bukan adjacency matrix?
b) Untuk aplikasi GPS navigation, informasi apa saja yang perlu disimpan pada vertex dan edge?
c) Apa perbedaan antara strongly connected dan weakly connected pada directed graph? Berikan contoh masing-masing.
a) Tuliskan fungsi int[][] listToMatrix(Map<Integer, List<Integer>> adjList, int n) yang mengkonversi adjacency list ke adjacency matrix.
b) Tuliskan fungsi Map<Integer, List<Integer>> matrixToList(int[][] matrix) yang mengkonversi adjacency matrix ke adjacency list.
- Cormen, T. H., et al. (2009). Introduction to Algorithms (3rd ed.). MIT Press.
- Sedgewick, R., & Wayne, K. (2011). Algorithms (4th ed.). Addison-Wesley.
- GeeksforGeeks - Graph Data Structure
- Visualgo - Graph
- CP-Algorithms - Graph