You are on page 1of 16

TRƯỜNG ĐẠI HỌC GIAO THÔNG VÂN TẢI

KHOA CÔNG NGHỆ THÔNG TIN


o0o

Bài tập lớn môn học

CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT

Giảng viên hướng dẫn: TS. Hoàng Văn Thông


Sinh viên thực hiện: Đỗ Minh Giang
Lớp: CNTT VA 1

Hà Nội tháng 11 năm 2022

1
Mụ c Lụ c
Hà Nội tháng 11 năm 2022................................................................2
Đề Bài................................................................................................2
Phân tích bài toán............................................................................3
Phân tích đề bài:............................................................................3
Mô tả chức năng của từng lớp, từng phương thức..........................4
Phân tích thời gian chạy của từng phương thức có trong các lớp....14
Danh sách tài liệu tham khảo...........................................................15

1
I.Đề Bài

1. Xây dựng lớp biểu diễn đồ thị đồ thị (Graph) vô hướng có trọng số bằng
danh sách kề. Mỗi đỉnh của đồ thị là một số tự nhiên có giá trị duy nhất
trong đồ thị. Mỗi cung của đồ thị được xác lập bằng một cặp đỉnh và một
trọng số là số thực.
2. Cài đặt các thao tác cơ bản trên đồ thị như sau
− Khởi tạo một đồ thị ban đầu rỗng có n đỉnh
− InsertEdge(int s, int d, float weight): bổ sung một cung có trọng số w
giữa hai đỉnh u, v (u, v<=n)
− InsertVertex(name): thêm một đỉnh mới vào đồ thị (đỉnh n+1, n+2,…)
− GetWeight(int s, int d): lấy ra trọng số của một cạnh
− Print: hiển thị hiện trạng của đồ thị
− Cài đặt thuật toán Dijkstra tìm đường đi ngắn nhất trong đồ thị
3. Xây dựng một chương trình nhận đầu vào là một file text chứa thông tin về
một đồ thị cho trước, tạo lập đồ thị, hiển thị đồ thị lên và từng bước của quá
trình tìm đường đi ngắn nhất từ đỉnh (u, v) được người dùng nhập từ bàn
phím.

2
Phân tích bài toán
Phân tích đề bài:
1.1. Xây dựng một đồ thị (Graph) vô hướng có trọng số là một số thực
bằng danh sách kề.
1.2. Với các thao tác sau:
1.2.1. Khởi tạo một đồ thị ban đầu rỗng có n đỉnh.
1.2.2. Tạo 1 phương thức InsertEdge để bổ sung trọng số w giữa
hai đỉnh u, v với u, v nhỏ hơn n.
1.2.3. Tạo 1 phương thức thêm 1 đỉnh mới cho đồ thị InsertVertex.
1.2.4. Tạo 1 phương thức lấy trọng số GetWeight.
1.2.5. Tạo 1 phương thức in trạng thái của đồ thị Print.
1.2.6. Cài đặt thuật toán Dijkstra để tìm đường đi ngắn nhất trong
đồ thị.
1.3. Xây dựng chương trình nhận đầu vào là một file text bao gồm các
thông tin của đồ thị, in đồ thị lên màn hình, hiển thị quá trình tìm
đường đi ngắn nhất từ (u,v) được người dùng nhập từ bàn phím.

3
Mô tả chức năng của từng lớp, từng phương thức.

- Lớp Node:

Lưu tên đỉnh và trọng số


Và biến con trỏ *next sẽ lưu địa chỉ của node tiếp theo trong danh sách liên kết.
Với Node(int vertex) truyền 1 kiểu dữ liệu là kiểu nguyên làm tên đỉnh, sau đó gán
tên đỉnh chính bằng dữ liệu vừa truyền và cho trọng số bằng -1 vì trọng số cần xác
định với 2 đỉnh, tiếp đó con trỏ next sẽ được gán bằng null vì danh sách mới khởi tạo
1 node.

4
- Lớp Graph:

Được khởi tạo với 2 thuộc tính là numVer để lưu số đỉnh của đồ thị và con trỏ mang
kiểu dữ liệu Node trỏ tới địa chỉ của mảng danh sách liên kết đơn.
Phương thức khởi tạo Constructor có đối là số đỉnh của đồ thị int numVer. Đầu tiên
sử dụng con trỏ this gán giá trị đỉnh bằng giá trị truyền vào numVer. Tiếp theo khởi
tạo một list với kiểu dữ liệu node và số đỉnh cộng với 3 (để lưu giá trị của 2 đỉnh và 1
trọng số). Sử dụng vòng for để duyệt hết giá trị của của biến. Tiếp tục khởi tạo một
con trỏ temp kiểu dữ liệu Node để tạo 1 nốt mới sau đó gán biến temp vào danh sách
liên kết đơn list.

5
Phương thức InsertEdge thuộc lớp Graph với đầu vào được truyền đỉnh thứ 1 int s và
đỉnh thứ 2 int d và trọng số có kiểu số thực double. Đầu tiên khởi tạo một biến temp
với kiểu dữ liệu node. Sau đó con trỏ next sẽ trỏ đến địa chỉ của của s. Sau đó gán giá
trị của phần tử đầu tiên của danh sách liên kết bằng temp. Và cuối cùng gán trọng số
giữ 2 đỉnh d và s bằng biến weight.

6
Phương thức InsertVertex thêm một đỉnh của đồ thị. Đầu tiên cộng thêm 1 vào biến
số đỉnh của đồ thị numVer. Tiếp theo khởi tạo con trỏ temp có kiểu dữ liệu là node
và truyền số đỉnh vào. Sau đó thêm vào danh sách liên kết và gán bằng biến temp.

7
Phương thức in đồ thị theo danh sách kề ra ngoài màn hình. Sử dụng vòng For để
duyệt từ i = 0 đến i = số đỉnh. Khởi tạo một biến temp bằng phần tử thứ i trong danh
sách liên kết đơn. Tiếp tục sử dụng vòng lặp while khi nào biến team khác rỗng. Lấy
ra đỉnh và trọng số đi kèm trong danh sách liên kết rồi in ra màn hình. Mỗi vòng lặp
while gắn temp bằng địa chỉ của node tiếp theo.

8
Hai phương thước đọc dữ liệu. Phương thức thứ nhất Read với đối số truyền vào là n
là số đỉnh của đồ thị. Khai báo 2 biến a, b sẽ là từng đỉnh của đồ thị và biến c kiểu dữ
liệu số thực nhận trọng số giữa 2 đỉnh. Sử dụng vòng for để duyệt từ phần tử thứ 0 tới
thứ n và nhận 3 giá trị a, b, c sau đó con trỏ this sẽ trỏ tới phương thức InsertEdge để
tạo 1 cạnh trong đồ thị với 2 đỉnh là giá trị a, b và trọng số c.
Phương thức đọc init là phương thức đọc file nhận dữ liệu cho thuật toán Dijstra. Đầu
tiên là câu lệnh mở file và chỉ với chức năng đọc file.

9
Bước 1: Từ đỉnh gốc, khởi tạo khoảng cách tới chính nó là 00, khởi tạo khoảng cách nhỏ
nhất ban đầu tới các đỉnh khác là +\infty+∞. Ta được danh sách các khoảng cách tới các
đỉnh.

Bước 2: Chọn đỉnh a có khoảng cách nhỏ nhất trong danh sách này và ghi nhận. Các lần
sau sẽ không xét tới đỉnh này nữa.

Bước 3: Lần lượt xét các đỉnh kề b của đỉnh a. Nếu khoảng cách từ đỉnh gốc tới
đỉnh b nhỏ hơn khoảng cách hiện tại đang được ghi nhận thì cập nhật giá trị và đỉnh
kề a vào khoảng cách hiện tại của b.

10
Bước 4: Sau khi xét tất cả đỉnh kề b của đỉnh a. Lúc này ta được danh sách khoảng cách
tới các điểm đã được cập nhật. Quay lại Bước 2 với danh sách này. Thuật toán kết thúc
khi chọn được khoảng cách nhỏ nhất từ tất cả các điểm.

Hai phương thức truy vết và phương thức in dùng để ghi lại đường đi, các đỉnh đã duyệt
qua và lưu vào stack. Sau đó in ra đường đi ngắn nhất đã tìm được.

11
12
13
Phân tích thời gian chạy của từng phương thức có trong các lớp

void InsertEdge(int s,int d,double weight)


Bao gồm 2 câu lệnh khởi tạo và 6 câu lệnh gán. Nên thời gian chạy của phương
thức là:
O(1)

void InsertVertex()
Bao gồm 1 câu lệnh khởi tạo vào 2 câu lệnh gán, thời gian chạy của phương
thức là:
O(1)

void Print()
Bao gồm 2 vòng lặp lồng nhau và 2 câu lệnh in, thời gian chạy của phương thức là:
O(mn) + O(1)

void Read(int n)
Phương thức gòm những câu lệnh khởi tạo và 1 vòng lặp và đệ quy nên thời gian
chạy:
O(log n)

void init()

Bao gồm 2 vòng lặp có thời gian chạy là


O(1) + O(n) + O(n)

void DIJKSTRA()
Thời gian chạy của thuật toán trên là
O(n)
14
Danh sách tài liệu tham khảo

https://gist.github.com Nên tảng chia sẻ giữa các lập trình viên.

https://chidokun.github.io/2021/09/dijkstra-algorithm Tài liệu và ý


tưởng về thuật toán Dijkstra.

https://usaco.guide/bronze/time-comp?
lang=cpp&fbclid=IwAR3c5bRxhlkRXC22fglKAYhPcag-
S8CNV5fNaq_fScU0Q4skQazlkOlaa0I Tài liệu tham khảo phân tích
thời gian chạy của thuật toán.

https://topdev.vn Tài liệu tham khảo danh sách liên kết đơn.

15

You might also like