Tổng quan về Đồ thị
Cấu trúc Graph (đồ thị) có rất nhiều ứng dụng trong thực tiễn. Bài viết này sẽ note lại tổng quan những điểm chính về việc implement cấu trúc dữ liệu này.
Mục lục
1. Đồ thị
Theo định nghĩa, Đồ thị là một tập hữu hạn các đỉnh và các cạnh kết nối các đỉnh. Chúng ta sẽ không đi quá sâu về lý thuyết đồ thị mà chỉ điểm lại những nét chính trong cách cài đặt cấu trúc dữ liệu Graph
.
Ví dụ về một đồ thị vô hướng như bên dưới:
Trong một số trường hợp, chúng ta sẽ cần dùng tên đỉnh. Tuy nhiên, tên đỉnh không quá quan trọng nên chúng ta sẽ đặt tên đỉnh là các số nguyên từ $0$ đến $V-1$. Một Graph
sẽ có V
đỉnh và E
cạnh. Việc định nghĩa thành các phương thức của đối tượng sẽ giúp việc viết các giải thuật đơn giản hơn.
Định nghĩa API cho Graph
:
public class Graph
--------------------------------------------
Graph(int V)
int V()
int E()
void addEdge(int v, int w)
Iterable<Integer> adj(int v)
Các phương thức cơ bản nhất:
- Graph(int V): Hàm khởi tạo với tham số đầu vào là số lượng đỉnh.
- V(): Trả về số lượng đỉnh.
- E(): Trả về số lượng cạnh.
- addEdge(int v, int w): Thêm một cạnh vào đồ thị, truyền 2 đỉnh
v
vàw
. - adj(int v): Lấy danh sách các đỉnh kề của đỉnh
v
.
2. Biểu diễn đồ thị
Có 2 cách biểu diễn phổ biến nhất là dùng ma trận kề (adjacency matrix) và danh sách kề (adjacency list).
2.1. Adjacency matrix
Khi biểu diễn graph bằng adjacency matrix, ta dùng một ma trận vuông $n \times n$ với $n$ là số đỉnh của graph. Mỗi dòng thể hiện một đỉnh, mỗi cột biểu diễn vị trí mà ở đó đỉnh có kết nối tới.
Ví dụ với Đồ thị 1 trên, ma trận kề sẽ là:
Cách implement tham khảo:
- java
1 |
|
Cách biểu diễn này có nhiều ưu điểm như:
- Tác vụ thêm cạnh nhanh do chỉ cần bật giá trị trong ma trận thành 1.
- Kiểm tra 2 đỉnh có kết nối nhau chỉ tốn $O(1)$.
Tuy nhiên, nó cũng có một số hạn chế:
- Do phải lưu trữ bằng một ma trận $n \times n$, nếu đồ thị có hàng triệu điểm thì rất tốn chi phí để duyệt cũng như lưu trữ.
- Không thể biểu diễn cạnh song song có trọng số.
2.2. Adjacency list
Với adjacency list, chúng ta sẽ lưu một mảng các đỉnh, mỗi đỉnh chứa một danh sách các đỉnh khác mà nó kết nối tới.
- java
1 |
|
Ưu điểm của danh sách kề:
- Không như ma trận kề, danh sách kề không tốn dung lượng lưu trữ cho những cạnh không tồn tại. Vì vậy, nó có thể biểu diễn và lưu trữ hàng triệu đỉnh.
- Biểu diễn được cạnh song song.
Nhược điểm chủ yếu là:
- Việc remove cạnh sẽ tốn chi phí để duyệt danh sách.
- Chi phí kiểm tra 2 cạnh có kết nối nhau không sẽ lớn hơn ma trận kề do phải duyệt danh sách.
3. Mở rộng
Cấu trúc ở trên khá đơn giản, để giải quyết yêu cầu phức tạp hơn cần mở rộng nó, dưới đây là một số gợi ý mở rộng cấu trúc đồ thị.
3.1. Trọng số
Mỗi cạnh thường có một trọng số biểu thị cho chi phí từ một đỉnh sang đỉnh khác. Ma trận kề có thể biểu diễn dễ dàng trọng số. Giá trị trong ma trận kề sẽ biểu thị trọng số. Giá trị $\infty$ biểu thị 2 đỉnh không kết nối với nhau.
Dưới đây là cách implement tham khảo cho WeightedGraph
sử dụng ma trận trọng số.
- java
1 |
|
Để biểu diễn bằng danh sách kề, trước hết chúng ta cần tạo class Edge
biểu diễn một cạnh. Class Edge
implement Comparable<Edge>
giúp thuận tiện cho các thao tác sort, so sánh.
Các method của Edge
:
- weight(): Trả về trọng số của cạnh hiện tại.
- either(): Trả về đỉnh đầu trong cạnh.
- other(int v): Trả về cạnh còn lại trong đồ thị vô hướng, nếu là đồ thị có hướng thì trả về đỉnh cuối và không cần tham số đầu vào nữa.
- java
1 |
|
Danh sách kề lúc này sẽ là một danh sách các cạnh Edge
.
- java
1 |
|
3.2. Đồ thị có hướng
Đồ thị có hướng là dạng đồ thị có tập đỉnh được nối với các cạnh có hướng. Cả ma trận kề và danh sách kề đều biểu diễn được đồ thị có hướng.
Ví dụ đồ thị sau:
3.3. Vòng khuyên
Một vòng khuyên (self-loop) là một cạnh nối 1 đỉnh với chính nó.
Ví dụ về vòng khuyên:
3.4. Cạnh song song
Cạnh song song (parallel edges) xuất hiện khi có nhiều hơn 1 cạnh nối cùng một cặp đỉnh. Đồ thị biểu diễn bằng danh sách kề có thể biểu diễn cạnh song song. Ma trận kề cũng có thể biểu diễn cạnh song song khi giá trị trong ma trận biểu thị số lượng cạnh nối. Tuy nhiên, không thể dùng ma trận trọng số để vừa biểu diễn cạnh song song, vừa biểu diễn trọng số.
Ví dụ:
Bình luận
Cảm ơn bạn
Your comment has been submitted and will be published once it has been approved. 😊
OK