Graph Data Structure คืออะไร?
Graph ประกอบด้วย Vertices (Nodes) และ Edges (Connections) ใช้แทนความสัมพันธ์ระหว่างวัตถุ
ประเภท Graph
- Directed (Digraph) - Edge มีทิศทาง (A → B)
- Undirected - Edge ไม่มีทิศทาง (A ↔ B)
- Weighted - Edge มีน้ำหนัก/ค่าใช้จ่าย
- Unweighted - Edge ไม่มีน้ำหนัก
Graph Representations
| Representation | Space | Add Edge | Check Edge | เหมาะสำหรับ |
|---|---|---|---|---|
| Adjacency Matrix | O(V²) | O(1) | O(1) | Dense Graph, V น้อย |
| Adjacency List | O(V + E) | O(1) | O(deg(V)) | Sparse Graph, General Purpose ⭐ |
| Edge List | O(E) | O(1) | O(E) | Simple, Edge-centric |
Implementation: Adjacency List ด้วย HashMap
ใช้ HashMap<Vertex, List<Vertex>> - ยืดหยุ่น รองรับ Vertex ใดๆ
Edge Class
class Edge {
int source;
int destination;
Edge(int source, int destination) {
this.source = source;
this.destination = destination;
}
}
Graph Class (Edge List Representation)
public class Graph {
int vertices;
int edges;
Edge[] edgeArray;
Graph(int vertices, int edges) {
this.vertices = vertices;
this.edges = edges;
this.edgeArray = new Edge[edges];
for (int i = 0; i < edges; i++) {
edgeArray[i] = new Edge(0, 0);
}
}
}
ตัวอย่างที่ 1: Edge List (จาก Source)
public class Graph {
class Edge {
int source, destination;
}
int vertices, edges;
Edge[] edge;
Graph(int vertices, int edges) {
this.vertices = vertices;
this.edges = edges;
edge = new Edge[edges];
for (int i = 0; i < edges; i++) {
edge[i] = new Edge();
}
}
public static void main(String[] args) {
int verticesCount = 5;
int edgesCount = 8;
Graph graph = new Graph(verticesCount, edgesCount);
System.out.println("A graph object is defined.");
// กำหนด Edges
graph.edge[0] = new Edge(); graph.edge[0].source = 1; graph.edge[0].destination = 2;
graph.edge[1] = new Edge(); graph.edge[1].source = 1; graph.edge[1].destination = 3;
graph.edge[2] = new Edge(); graph.edge[2].source = 1; graph.edge[2].destination = 4;
graph.edge[3] = new Edge(); graph.edge[3].source = 2; graph.edge[3].destination = 4;
graph.edge[4] = new Edge(); graph.edge[4].source = 2; graph.edge[4].destination = 5;
graph.edge[5] = new Edge(); graph.edge[5].source = 3; graph.edge[5].destination = 4;
graph.edge[6] = new Edge(); graph.edge[6].source = 3; graph.edge[6].destination = 5;
graph.edge[7] = new Edge(); graph.edge[7].source = 4; graph.edge[7].destination = 5;
System.out.println("The connections between the edges of the Graph are: ");
for (int i = 0; i < edgesCount; i++) {
System.out.println(graph.edge[i].source + " - " + graph.edge[i].destination);
}
}
}
ผลลัพธ์
A graph object is defined.
The connections between the edges of the Graph are:
1 - 2
1 - 3
1 - 4
2 - 4
2 - 5
3 - 4
3 - 5
4 - 5
ตัวอย่างที่ 2: OOP Style (แยกเมธอด)
public class Graph {
class Edge {
int source, destination;
}
int vertices, edges;
Edge[] edge;
Graph(int vertices, int edges) {
this.vertices = vertices;
this.edges = edges;
edge = new Edge[edges];
for (int i = 0; i < edges; i++) edge[i] = new Edge();
}
static void connectEdges(Graph g) {
g.edge[0] = new Edge(); g.edge[0].source = 1; g.edge[0].destination = 2;
g.edge[1] = new Edge(); g.edge[1].source = 1; g.edge[1].destination = 3;
g.edge[2] = new Edge(); g.edge[2].source = 1; g.edge[2].destination = 4;
g.edge[3] = new Edge(); g.edge[3].source = 2; g.edge[3].destination = 4;
g.edge[4] = new Edge(); g.edge[4].source = 2; g.edge[4].destination = 5;
g.edge[5] = new Edge(); g.edge[5].source = 3; g.edge[5].destination = 4;
g.edge[6] = new Edge(); g.edge[6].source = 3; g.edge[6].destination = 5;
g.edge[7] = new Edge(); g.edge[7].source = 4; g.edge[7].destination = 5;
}
static void print(Graph g, int edgesCount) {
System.out.println("The connections between the edges of the Graph are: ");
for (int i = 0; i < edgesCount; i++) {
System.out.println(g.edge[i].source + " - " + g.edge[i].destination);
}
}
public static void main(String[] args) {
int v = 5, e = 8;
Graph graph = new Graph(v, e);
System.out.println("A graph object is defined.");
connectEdges(graph);
print(graph, e);
}
}
Adjacency List Implementation (Modern, Recommended)
import java.util.*;
public class GraphAdjList {
// Adjacency List: Vertex -> List of Neighbors
private Map> adjList = new HashMap<>();
private boolean directed;
public GraphAdjList(boolean directed) {
this.directed = directed;
}
public void addVertex(int v) {
adjList.putIfAbsent(v, new ArrayList<>());
}
public void addEdge(int src, int dest) {
addVertex(src);
addVertex(dest);
adjList.get(src).add(dest);
if (!directed) {
adjList.get(dest).add(src);
}
}
public void printGraph() {
for (Map.Entry> entry : adjList.entrySet()) {
System.out.print(entry.getKey() + " -> ");
System.out.println(entry.getValue());
}
}
// BFS Traversal
public void bfs(int start) {
Set visited = new HashSet<>();
Queue queue = new LinkedList<>();
visited.add(start);
queue.offer(start);
while (!queue.isEmpty()) {
int v = queue.poll();
System.out.print(v + " ");
for (int neighbor : adjList.getOrDefault(v, Collections.emptyList())) {
if (!visited.contains(neighbor)) {
visited.add(neighbor);
queue.offer(neighbor);
}
}
}
}
// DFS Traversal
public void dfs(int start) {
Set visited = new HashSet<>();
dfsRecursive(start, visited);
}
private void dfsRecursive(int v, Set visited) {
visited.add(v);
System.out.print(v + " ");
for (int neighbor : adjList.getOrDefault(v, Collections.emptyList())) {
if (!visited.contains(neighbor)) {
dfsRecursive(neighbor, visited);
}
}
}
public static void main(String[] args) {
GraphAdjList graph = new GraphAdjList(false); // Undirected
graph.addEdge(1, 2);
graph.addEdge(1, 3);
graph.addEdge(2, 4);
graph.addEdge(3, 4);
graph.addEdge(4, 5);
graph.printGraph();
// 1 -> [2, 3]
// 2 -> [1, 4]
// 3 -> [1, 4]
// 4 -> [2, 3, 5]
// 5 -> [4]
System.out.print("\nBFS: "); graph.bfs(1); // 1 2 3 4 5
System.out.print("\nDFS: "); graph.dfs(1); // 1 2 4 5 3
}
}
Weighted Graph (มีน้ำหนัก)
class WeightedEdge {
int dest;
double weight;
WeightedEdge(int dest, double weight) {
this.dest = dest; this.weight = weight;
}
}
// Adjacency List สำหรับ Weighted Graph
Map> weightedGraph = new HashMap<>();
weightedGraph.computeIfAbsent(1, k -> new ArrayList<>()).add(new WeightedEdge(2, 10.5));
weightedGraph.computeIfAbsent(2, k -> new ArrayList<>()).add(new WeightedEdge(3, 5.0));
สรุป
- Graph = Vertices + Edges (Directed/Undirected, Weighted/Unweighted)
- Representations: Adjacency Matrix (Dense), Adjacency List (Sparse - แนะนำ), Edge List
- Java: ใช้
HashMap<V, List<V>>สำหรับ Adjacency List - Traversals: BFS (Queue), DFS (Stack/Recursion)
- Algorithms: Dijkstra (Shortest Path), Topological Sort, MST (Kruskal/Prim)