Trong bài báo cáo này, em xin được tập trung nghiên cứu cácvấn đề sau: Xây dựng lớp biểu diễn một bảng băm sử dụng một trong những hàmbăm đã học; Cài đặt lớp danh sách liên kết đơn mẫu,
Trang 1TRƯỜNG ĐẠI HỌC GIAO THÔNG VẬN TẢI HÀ NỘI
KHOA CÔNG NGHỆ THÔNG TIN
-BÀI TẬP LỚN MÔN: CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT
Giáo viên hướng dẫn : TS Hoàng Văn Thông
Sinh viên thực hiện: Trần Kim Anh
Mã sinh viên: 221230742
Lớp: CNTT4 – K63
Hà Nội, 2023
Trang 2TRƯỜNG ĐẠI HỌC GIAO THÔNG VẬN TẢI HÀ NỘI
KHOA CÔNG NGHỆ THÔNG TIN
-BÀI TẬP LỚN
Giáo viên hướng dẫn : TS Hoàng Văn Thông
Sinh viên thực hiện: Trần Kim Anh
Mã sinh viên: 221230742
Lớp: CNTT4 – K63
Trang 3Mục lục
Lời mở đầu 2
Bài 1 (Bài số 7) Xây dựng lớp biểu diễn một bảng băm sử dụng một trong những hàm băm đã học 3
1.1 Đề bài 3
1.2 Phân tích bài toán 3
1.2.1 Xác định yêu cầu bài toán, xác định các lớp, các thuộc tính, các phương thức của lớp 3
1.2.2 Mô tả chức năng của từng lớp, từng phương thức 4
1.3 Cài đặt các lớp và hàm main bằng C++ 7
1.4 Phân tích thời gian chạy của từng phương thức có trong các lớp 10
Bài 2 (Bài số 34): Cài đặt lớp danh sách liên kết đơn mẫu, bổ sung phương thức sắp xếp các phần tử theo thứ tự tăng dần hoặc dần tùy thuộc vào tham số 12
2.1 Đề bài: 12
2.2 Phân tích bài toán 12
2.2.1 Xác định yêu cầu bài toán 12
2.2.2 Xác đinh các lớp, các thuộc tính, các phương thức của lớp 13
2.2.3 Mô tả chức năng của từng lớp, từng phương thức 14
2.3 Cài đặt các lớp và hàm main bằng C++ 16
2.4 Phân tích thời gian chạy của từng phương thức có trong các lớp 20
Danh sách tài liệu tham khảo 21
Trang 4Lời mở đầu
Cấu trúc dữ liệu và giải thuật là môn học cơ bản nhưng vô cùngquan trọng đối với ngành Công nghệ thông tin nói chung và Khoahọc máy tính nói riêng Học phần này cung cấp những kiến thức và
kỹ năng để có thể tổ chức, truy xuất và xử lý dữ liệu một cách hiệuquả
Trong bài báo cáo này, em xin được tập trung nghiên cứu các
vấn đề sau: Xây dựng lớp biểu diễn một bảng băm sử dụng một trong những hàm băm đã học; Cài đặt lớp danh sách liên kết đơn mẫu, bổ sung phương thức sắp xếp các phần tử theo thứ tự tăng dần hoặc dần tùy thuộc vào tham số Đây là các bài toán phức tạp đòi hỏi phải vận dụng linh
hoạt và sáng tạo các kiến thức đã được trang bị qua môn học Bàitập lớn này đã giúp em phát triển các kỹ năng, tư duy logic và khảnăng giải quyết vấn đề
Qua đây, em xin dành lời cảm ơn chân thành đến thầy HoàngVăn Thông Thầy đã cung cấp cho cá nhân em nhưng kiến thức nềntảng của bộ môn Cấu trúc Dữ liệu và Giải thuật để qua đó em có thểhoàn thành được bài báo cáo này
Do bài báo cáo còn nhiều hạn chế và sai sót, em rất mongnhận được sự đánh giá và góp ý từ thầy Hoàng Văn Thông để em cóthể cải thiện kiến thức và kỹ năng của bản thân mình và hoàn thànhtốt hơn trong tương lai
Em xin chân thành cảm ơn!
Trang 5Bài 1 (Bài số 7) Xây dựng lớp biểu diễn một
bảng băm sử dụng một trong những hàm băm đã học.
a Nạp từ điển từ file vào bảng băm
b Tìm kiếm bằng phương pháp tìm kiếm trên bảng băm
c Sửa đổi các từ
d Thêm từ mới
e Xóa từ
f Lưu từ điển vào file
2 Xây dựng chương trình có các chức năng:
a Nạp từ điển từ file (có thể nạp tự động khi chạy chươngtrình)
b Tra từ điển (nhập vào một từ, hiển thị nghĩa của nó nếu
có trong từ điển)
c Sửa đổi từ
d Thêm từ mới
e Xóa từ
f Lưu từ điển vào file
1.2 Phân tích bài toán
1.2.1 Xác định yêu cầu bài toán, xác định các lớp, các thuộc tính, các phương thức của lớp
Yêu cầu của bài toán:
Trang 6 Xây dựng lớp biểu diễn một bảng băm
Sử dụng lớp bảng băm để xây dựng lớp biểu diễn từ điểnAnh Việt với các phương thức: Nạp từ điển từ file vào bảngbăm, tìm kiếm bằng phương pháp tìm kiếm trên bảng băm,sửa đổi các từ, thêm từ mới, xóa từ, lưu từ điển vào file
void insert(string word, string mean)
void inf(string fileName)
void outf(string fileName)
string findd(string word)
void edit(string word,string mean)
void del(string word)
Trang 71.2.2 Mô tả chức năng của từng lớp, từng phương thức
Danh sách liên kết đơn (Single linked list) là chuỗi
các Node (nút) được tổ chức theo thứ tự tuyến tính, các phần tử thuộc danh sách liên kết đơn được gọi là các Node và chúng nằm
dải rác trong bộ nhớ
Trong danh sách liên kết đơn mỗi phần tử đều liên kết với phần
tử đứng sau nó trong danh sách:
Trong đó node trong danh sách liên kết đơn được chia thànhhai thành phần chính đó là phần lưu giá trị và lưu địa chỉ liên kết củanode tiếp theo trong danh sách liên kết
Bảng băm, còn được gọi là Hash Tables, là một cấu trúc dữ
liệu trong khoa học máy tính Bảng băm sử dụng hàm băm để ánh
xạ từ giá trị xác định, được gọi là khóa (ví dụ như tên của một
người), đến giá trị tương ứng (ví dụ như số điện thoại của họ) Do đó,bảng băm là một mảng kết hợp
Hàm băm được sử dụng để chuyển đổi từ khóa thành chỉ số
(giá trị băm) trong mảng lưu trữ các giá trị tìm kiếm Trong trường hợp lý tưởng, hàm băm luôn chuyển đổi các khóa khác nhau đến cácchỉ số khác nhau
Bảng băm thường được sử dụng như một từ điển: mỗi phần tử
trong bảng băm là một cặp (khóa, giá trị) Nếu so sánh với mảng, khóa được xem như chỉ số của mảng, còn giá trị giống như giá trị mà
ta lưu tại chỉ số tương ứng
Trang 8 Trong bài toán, xây dựng lớp node: thêm thuộc tính là các chuỗi Eng, Viet để lưu trữ thông tin và con trỏ next để trỏ đến thành phần kế tiếp của danh sách
Chức năng: đóng vai trò như một khối xây dựng cơ bản cho cấu trúc dữ liệu cho danh sách liên kết
Trang 9chuỗi Eng và Viet để lưu trữ từ và nghĩa, cũng như một contrỏ ( next) trỏ đến node tiếp theo trong danh sách.
- tuDien() : Hàm khởi tạo của lớp tuDien Nó thiết lập các phần tửtrong bảng băm hash_table thành giá trị NULL
- int hashString(string a): Hàm băm chuỗi a thành số nguyên, dùng
để xác định vị trí lưu trữ của một từ trong bảng băm
- void insert(string word, string mean): Phương thức này chèn 1 từ
mới vào bảng băm Nó tạo ra một node mới với từ word và nghĩa
mean, sau đó chèn node này vào đầu danh sách liên kết tại chỉ
số được xác định bởi hàm băm
- void inf(string fileName): Dùng để nạp các từ tiếng anh và nghĩacủa nó từ file vào bảng băm
- void outf(string fileName): Dùng để lưu từ điển vào file
- string findd(string word): Dùng để tìm kiếm một từ trong bảngbăm và trả về nghĩa của từ đó Nếu không tồn tại từ đó thì nó sẽtrả về một thông báo lỗi
- void edit(string word,string mean): Dùng để sửa đổi nghĩa của 1
từ tiếng anh thành nghĩa mới Nếu từ đó không tồn tại trongbảng băm, nó sẽ in ra một thông báo lỗi
- void del(string word): Dùng để xóa từ tiếng anh ra khỏi từ điển,nếu từ đó không tồn tại trong bảng băm,
1.3 Cài đặt các lớp và hàm main bằng C++
Tên file: bai7.cpp
Trang 10int hashString(string a){//Ham bam chuoi a thanh so
}
//Ham chen chuoi
void insert(string word, string mean){
int index = hashString(word);
node *newNode = new node(word,mean);//tao 1 nodemoi
newNode->next = hash_table[index];
hash_table[index] = newNode;
}
Trang 11//Ham nap tu dien tu file vao bang bam
void inf(string fileName){
temp.substr(temp.find(":")+1,temp.size()-}file.close();
}
//Ham luu tu dien vao file
void outf(string fileName){
temp=temp->next;
}}
node *temp = hash_table[hashString(word)];
while(temp != NULL){//vong lap duyet qua dslk
if(temp->Eng == word)//neu node hien tai khop voi node chinh sua
return "tu "+word+" co nghia tieng viet la:
"+temp->Viet;
temp = temp->next;
}return"Khong tim thay tu nao la: "+word;
}
//Ham sua doi cac tu
void edit(string word,string mean){
Trang 12node *temp = hash_table[hashString(word)];
}cout<<"Khong ton tai "<<word<<" trong tu dien";}
//Ham xoa tu
void del(string word){
int index = hashString(word);//tinh toan chi so can xoa bang ham bam
node *temp = hash_table[index];//tao con tro tro den node dau tien trong dslk vi tri o chi so vua tinh
if(temp==NULL)//neu dslk nay rong thi thoat
(temp) = (temp)->next;
}}
Trang 13//Chinh sua tutd.edit("dog","con heo");
cout<<td.findd("dog")<<'\n';
//Them tu moitd.insert("bye","tam biet");
td.insert("Puppy","Cun con");
cout<<td.findd("bye")<<'\n';
//Xoa tutd.del("Puppy");
- Gọi hàm hashString(): O(m)
- Thêm node vào danh sách liên kết: O(1)
=> Độ phức tạp là O(m)
Hàm inf():
- Đọc dữ liệu từ file: O(1)
- Gọi hàm insert() cho mỗi từ đọc được: O(nm) với n là số từ trong file
=> Độ phức tạp là O(nm)
Hàm findd():
- Gọi hàm hashString(): O(m)
- Duyệt danh sách liên kết tại vị trí tìm được: O(n)
=> Độ phức tạp là O(m + n) ~ O(n)
Trang 14 Hàm edit(): Tương tự findd() nên độ phức tạp là O(n)
Hàm del(): Tương tự findd() nên độ phức tạp là O(n)
Hàm outf():
- Duyệt qua toàn bộ bảng băm: O(n)
- Duyệt danh sách liên kết tại mỗi vị trí: O(n)
- Ghi dữ liệu ra file: O(1)
=> Độ phức tạp của outf() là O(n) * O(n) = O(n^2)
=> Cả chương trình: Độ phức tạp là O(n^2)
Trang 15Bài 2 (Bài số 34): Cài đặt lớp danh sách liên
kết đơn mẫu, bổ sung phương thức sắp xếp các phần tử theo thứ tự tăng dần hoặc dần tùy thuộc vào tham số.
2.1 Đề bài:
1 Cài đặt lớp danh sách liên kết đơn mẫu, bổ sung phươngthức sắp xếp các phần tử theo thứ tự tăng dần hoặc dần tùy thuộcvào tham số
2 Ứng dụng giải các bài toán sau:
a Viết chương trình con nhận vào từ bàn phím một dãy sốnguyên, lưu trữ nó trong một danh sách có thứ tự tăng dần không cóhai phần tử trùng nhau, theo cách sau: với mỗi phần tử được nhậpvào chương trình con phải tìm kiếm xem nó có trong danh sáchchưa, nếu chưa có thì xen nó vào danh sách cho đúng thứ tự
b Viết chương trình con trộn hai danh sách liên kết chứa các
số nguyên theo thứ tự tăng dần để được một danh sách cũng có thứ
tự tăng dần
c Viết chương trình con tách một danh sách chứa các sốnguyên thành hai danh sách: một danh sách gồm các số chẵn còndanh sách kia chứa các số lẻ
2.2 Phân tích bài toán
2.2.1 Xác định yêu cầu bài toán
Cài đặt lớp danh sách liên kết đơn mẫu, bổ sung phương thứcsắp xếp các phần tử theo thứ tự tăng dần
Trang 16Viết chương trình con nhận vào từ bàn phím một dãy sốnguyên, lưu trữ nó trong một danh sách có thứ tự tăng dần không cóhai phần tử trùng nhau, tương tự như việc tạo 1 set
Viết chương trình con trộn hai danh sách liên kết chứa các sốnguyên theo thứ tự tăng dần để được một danh sách cũng có thứ tựtăng dần
Viết chương trình con tách một danh sách chứa các số nguyênthành hai danh sách: một danh sách gồm các số chẵn còn danh sáchkia chứa các số lẻ
2.2.2 Xác đinh các lớp, các thuộc tính, các phương thức của lớp
Trang 17node<T>*& gethead()node<T>* makeNode(T x)bool isExist(T x, node<T> *head)void insertSorted(node<T>*& head, T x)void merge(llist<T>& list1, llist<T>& list2)void splitEvenOdd(llist<T>& evenList, llist<T>& oddList) void printList()
2.2.3 Mô tả chức năng của từng lớp, từng phương thức
Xây dựng 1 lớp node mẫu để danh sách liên kết có thể làmviệc với bất cứ kiểu dữ liệu nào Lớp node tạo một biến đểlưu giá trị của node và 1 con trỏ trỏ đến node tiếp theotrong danh sách liên kết
Chức năng: đóng vai trò như một khối xây dựng cơ bản cho cấu trúc dữ liệu cho danh sách liên kết
Trang 18node(T v, node *N = NULL){
- node<T>*& gethead(): truy cập đến node đầu tiên trongdanh sách liên kết
- llist(node<T> *h = NULL): hàm khởi tạo giá trị cho node đầutiên trong danh sách liên kết,
- node<T>* makeNode(T x): hàm tạo một node mới trongdanh sách liên kết với giá trị là x và trả về con trỏ đến nodemới đó
Trang 19- bool isExist(T x, node<T> *head): hàm kiểm tra giá trị đã có
ở trong danh sách liên kết chưa, nếu tồn tại nó sẽ trả về
true, không tồn tại nó sẽ trả về false
- void insertSorted(node<T>*& head, T x): hàm chèn mộtnode vào danh sách liên kết sao cho danh sách liên kết mớiđược sắp xếp Ở đây thuật toán sắp xếp chèn được sử dụng
để sắp xếp danh sách theo thứ tự tăng dần
- void merge(llist<T>& list1, llist<T>& list2): hàm trộn 2danh sách liên kết lại với nhau
- void splitEvenOdd(llist<T>& evenList, llist<T>& oddList):hàm chia danh sách liên kết thành 2 danh sách, 1 danh sáchchứa các số chẵn và 1 danh sách chứa các số lẻ
- void printList(): hàm in danh sách liên kết ra màn hình Cácgiá trị được in ra theo thứ tự từ head đến cuối danh sách
Trang 20//ham kiem tra xem gia tri do ton tai trong dslk chua,
de tranh trung lap
bool isExist(T x, node<T> *head){
node<T> *temp = head;
Trang 21}
//ham chen 1 node vao dslk sao cho dslk moi duoc sap xep tang
void insertSorted(node<T>*& head, T x){
if(head == NULL || head->value >= x){
node<T> *newNode = makeNode(x);
newNode->next = head;
head = newNode;
} else {
node<T> *current = head;
while(current->next != NULL && current->next->value
node<T>* a = list1.gethead();
node<T>* b = list2.gethead();
node<T>* result = NULL;
while(a != NULL && b != NULL){
Trang 22node<T>* temp = head;
llist<int> list1, list2;
cout << "Nhap so phan tu cua danh sach thu nhat: ";
Trang 252.4 Phân tích thời gian chạy của từng phương
thức có trong các lớp
makeNode(T x):
- Độ phức tạp là O(1) vì hàm này chỉ thực hiện một số lượng hữu hạn các thao tác
isExist(T x, node<T> *head):
- Độ phức tạp là O(n) vì hàm này duyệt qua toàn bộ danh sách liên kết
Hàm insertSorted()
- Duyệt danh sách (để tìm phần tử chèn): O(n)
- Tạo node mới (trái hoặc phải): O(1)
- Chèn vào list: O(1)
Trang 26Danh sách tài liệu tham khảo
Tham khảo code - Được viết bởi tác giả: Arash Partow vào năm2002
https://www.partow.net/programming/hashfunctions/
index.html#StringHashing