TRƯỜNG ĐẠI HỌC TÀI NGUYÊN VÀ MÔI TRƯỜNG THÀNH PHỐ HỒ CHÍ MINH
KHOA HỆ THỐNG THÔNG TIN VÀ VIỄN THÁM
BÁO CÁOLÍ THUYẾT ĐỒ THỊ
DEMO CHƯƠNG TRÌNH :MA TRẬN KỀDANH SÁCH KỀ
Sinh viên thực hiện: Nhóm 10Lớp : 11_ĐH_CNTT3Khoá : 2022 – 2026Giảng viên : Lê Tuấn Thu
TP Hồ Chí Minh, tháng 2 năm 2024
Trang 1
Trang 2TRƯỜNG ĐẠI HỌC TÀI NGUYÊN VÀ MÔI TRƯỜNG THÀNH PHỐ HỒ CHÍ MINH
KHOA HỆ THỐNG THÔNG TIN VÀ VIỄN THÁM
BÁO CÁOLÍ THUYẾT ĐỒ THỊ
DEMO CHƯƠNG TRÌNH :MA TRẬN KỀDANH SÁCH KỀ
Sinh viên thực hiện: Nhóm 10Lớp : 11_ĐH_CNTT3 Khoá : 2022 – 2026
Giảng viên hướng dẫn : Lê Tuấn Thu
TP Hồ Chí Minh, tháng 2 năm 2024
Trang 2
Trang 39 1150080110 Nguyễn Ngọc Tuyết Nhiên Chich gai
1 Ma trận kề1.1 Ma trận kề là gì ?
Trang 3
Trang 4Ma trận kề là cách biểu diễn đồ thị G = {V,E} dưới dạng ma trận các giá trị boolean cókích thước bằng với số đỉnh của đồ thị
1.2 Tính chất của ma trận kề :
Tính chất của ma trận kề của đồ thị vô hướng:
Tính đối xứng: a[i,j]=a[j,i], i,j=1,2, .,n.
Khai báo thư viện fstream :
Thư viện fstream trong C++ được sử dụng để thực hiện các thao tác đọc và ghi vào các tệp (file) Với các lớp :
ifstream (Input File Stream): Dùng để đọc dữ liệu từ tệp.ofstream (Output File Stream): Dùng để ghi dữ liệu vào tệp.
Trang 4
Trang 5Viết hàm nhập ma trận từ bàn phím với class ofstream :
void nhapmatran(int a[][100]): Đây là khai báo của hàm nhapmatran trong C++
Hàm này không trả về bất kỳ giá trị nào (void), nhưng nhận một mảng hai chiều làm a
tham số đầu vào.
int row, col;: Khai báo hai biến row và col để lưu số hàng và số cột của ma trận mà
người dùng sẽ nhập vào.
ofstream file("matranke.txt");: Tạo một đối tượng của lớp ofstream (output file
stream) có tên file và mở tệp có tên là "matranke.txt" để ghi dữ liệu vào.
cout << "Nhap so hang : ";: Hiển thị thông báo để yêu cầu người dùng nhập số hàng
Trang 6file << row; file << " "; file << col; file << "\n";, , , : Ghi số hàng và số cột của ma trận vào tệp "matranke.txt".
for (int i = 0; i < row; i++) {: Bắt đầu vòng lặp để nhập giá trị của các phần tử trong
ma trận hàng từng hàng.
for (int j = 0; j < col; j++) {: Bắt đầu vòng lặp để nhập giá trị của các phần tử trong
mỗi hàng của ma trận.
cout << "Nhap vao a[" << i << "][" << j << "] : ";: Hiển thị thông báo yêu cầu
người dùng nhập giá trị của phần tử a[i][j] trong ma trận.
cin >> a[i][j];: Nhận giá trị của phần tử a[i][j] từ người dùng.
file << a[i][j] << "\t";: Ghi giá trị của phần tử a[i][j] vào tệp "matranke.txt", cách
nhau bởi một dấu tab.
file << "\n";: Xuống dòng để chuyển sang hàng mới trong tệp "matranke.txt" sau khi
nhập xong một hàng của ma trận.
file.close();: Đóng tệp "matranke.txt" sau khi đã ghi xong dữ liệu ma trận vào tệp.
Viết hàm xuất mà trận từ file txt với class ifstream :
void xuatmatran(int b[][100]) :Khai báo hàm xuatmatran nhận một mảng hai chiều b
dưới dạng tham số Kích thước của mảng là 100x100.
int row, col; Khai báo hai biến nguyên row và col để lưu số hàng và số cột của ma trận.
ifstream file ("matranke.txt");Mở tệp có tên "matranke.txt" để đọc dữ liệu từ đó bằng lớp ifstream.
file >> row >> col;Đọc hai giá trị từ tệp "matranke.txt" và gán chúng cho row và col, giả định rằng tệp chứa hai số nguyên đầu tiên lần lượt là số hàng và số cột của ma trận.cout << "so hang va so cot cua ma tran : " << row << ", " << col << endl;Hiển thị số hàng và số cột của ma trận lên màn hình.
Trang 6
Trang 7for(int i = 0; i < row; i++){ for(int j = 0; j < col; j++){ file >> b[i][j]; cout << b[i][j] << " "; }
cout << endl;
} : Đọc dữ liệu từ tệp "matranke.txt" và gán giá trị cho mảng b Vòng lặp đầu tiên
duyệt qua các hàng của ma trận, vòng lặp thứ hai duyệt qua các cột của ma trận Mỗi giá trị được đọc từ tệp và gán vào phần tử tương ứng của mảng , và sau đó hiển thị b
giá trị đó ra màn hình.
file.close(); Đóng tệp "matranke.txt" sau khi hoàn thành việc đọc dữ liệu.
Chạy chương trình :
Tạo được file txt chung đường dẫn với đường dẫn lưu chương trình :
Dữ liệu của file txt :
Trang 7
Trang 82 Danh sách kề 2.1 Danh sách kề là gì ?
Là cách biểu diễn đồ thị dưới dạng danh sách kề thường được sử dụng Trong biểu diễn này, với mỗi đỉnh v của đồ thị chúng ta lưu trữ danh sách các đỉnh kề với nó mà ta ký hiệu là Ke(v), nghĩa là:
Trang 92.2 Demo chương trình
struct node { int data; node* next; };: Định nghĩa một cấu trúc node đại diện cho
một đỉnh trong đồ thị Mỗi node chứa một số nguyên (data) và một con trỏ next trỏ tới node tiếp theo trong danh sách liên kết.
node* p, * DSKe[MAX];: Khai báo biến con trỏ p và mảng DSKe gồm MAX phần
tử, mỗi phần tử của mảng là một con trỏ đến node, được sử dụng để lưu danh sách kề của từng đỉnh trong đồ thị.
Trang 9
Trang 10node* Taonode(int x) { }: Hàm này tạo một node mới có dữ liệu là x và trả về con
trỏ đến node mới tạo.
node* Themnode(node* head, int x) { }: Hàm này thêm một node mới có giá trị x
vào cuối danh sách liên kết đang tồn tại và trả về con trỏ đầu của danh sách liên kết sau khi thêm.
Trang 10
Trang 11void DanhSachKe() {: Khai báo hàm DanhSachKe() Hàm này không trả về giá trị
(void) và không có tham số đầu vào.
int dinhdau, dinhcuoi;: Khai báo hai biến nguyên dinhdau và dinhcuoi để lưu trữ
đỉnh đầu và đỉnh cuối của một cạnh khi người dùng nhập vào.
cout << "Nhap so dinh cua do thi : ";: In ra màn hình thông báo yêu cầu người dùng
cin >> socanh;: Nhận giá trị số cạnh của đồ thị từ người dùng qua bàn phím và lưu
vào biến socanh.
for (int i = 0; i < sodinh; i++) { DSKe[i] = NULL; }: Khởi tạo danh sách kề của mỗi
đỉnh bằng NULL Duyệt qua mảng DSKe và gán giá trị NULL cho từng phần tử.
for (int i = 0;i < socanh;i++) {: Bắt đầu vòng lặp để nhập từng cạnh của đồ thị.cout << "Nhap dinh dau va dinh cuoi cua canh " << i + 1 << " : ";: In ra màn hình
thông báo yêu cầu người dùng nhập đỉnh đầu và đỉnh cuối của cạnh thứ i+1.
cin >> dinhdau >> dinhcuoi;: Nhận giá trị của đỉnh đầu và đỉnh cuối của cạnh từ
người dùng qua bàn phím và lưu vào các biến dinhdau và dinhcuoi
DSKe[dinhdau] = Themnode(DSKe[dinhdau], dinhcuoi);: Thêm đỉnh cuối vào
danh sách kề của đỉnh đầu Hàm Themnode() được gọi để thêm đỉnh cuối vào danh sách kề của đỉnh đầu.
DSKe[dinhcuoi] = Themnode(DSKe[dinhcuoi], dinhdau);: Thêm đỉnh đầu vào
danh sách kề của đỉnh cuối Hàm Themnode() được gọi để thêm đỉnh đầu vào danh sách kề của đỉnh cuối.
Kết thúc vòng lặp for và kết thúc hàm DanhSachKe().
Trang 11
Trang 12void inDS() {: Khai báo hàm inDS() Hàm này không trả về giá trị (void) và không có
tham số đầu vào.
for (int i = 0; i < sodinh; i++) {: Bắt đầu vòng lặp để duyệt qua từng đỉnh trong đồ thị.cout << "Dinh " << i << " : ";: In ra màn hình thông báo cho biết đang in danh sách kề của đỉnh thứ i
node* temp = DSKe[i];: Khởi tạo con trỏ temp và trỏ nó vào đầu danh sách kề của đỉnh thứ i
cout<<"{";: In ra màn hình ký tự { để bắt đầu in danh sách kề của đỉnh.
while (temp->next != NULL) {: Bắt đầu vòng lặp while để duyệt qua danh sách kề
của đỉnh Vòng lặp dừng khi con trỏ temp trỏ đến phần tử cuối cùng của danh sách.
cout << temp->data << ", ";: In ra màn hình giá trị của đỉnh mà temp đang trỏ tới,
sau đó dấu phẩy để phân tách giữa các đỉnh.,
temp = temp->next;: Di chuyển con trỏ temp sang phần tử kế tiếp trong danh sách
cout<< temp->data <<"}\n";: Sau khi vòng lặp kết thúc, in ra giá trị của đỉnh cuối
cùng mà temp trỏ tới và ký tự để đóng danh sách kề của đỉnh Dòng này cũng in ra }
ký tự xuống dòng để chuyển xuống dòng mới cho việc in tiếp đỉnh tiếp theo.\n
Kết thúc vòng lặp for và kết thúc hàm inDS().
Trang 12
Trang 13Hàm main là hàm chính của chương trình, nơi bắt đầu thực thi Trong hàm main, chương trình gọi lần lượt hai hàm DanhSachKe() để nhập và xây dựng danh sách kề, và inDS() để in ra danh sách kề đã được xây dựng.
Chạy chương trình :
Trang 13