Hình 1: Cấu trúc danh sách liên kết đôi...2Hình 2: Minh họa thuật toán Quick sort trong danh sách liên kết đơn...2Hình 3: Minh họa thuật toán Quick sort trong danh sách liên kết đôi...5D
Trang 1HỌC VIỆN NGÂN HÀNG
KHOA HỆ THỐNG THÔNG TIN QUẢN LÝ
-
-BÁO CÁO BÀI TẬP NHÓM
Đề tài: SẮP XẾP DANH SÁCH LIÊN KẾT ĐÔI BẰNG
THUẬT TOÁN QUICK SORT
Giảng viên hướng dẫn : Nguyễn Thanh Thụy
Trang 2HỌC VIỆN NGÂN HÀNG KHOA HỆ THỐNG THÔNG TIN QUẢN LÝ
-
-BÁO CÁO BÀI TẬP NHÓM
Đề tài: SẮP XẾP DANH SÁCH LIÊN KẾT ĐÔI
BẰNG THUẬT TOÁN QUICK SORT
Danh sách thành viên
ST
T
Họ và tên Mã sinh viên Mức độ đóng góp
(%)
Chữ ký
1 Phan Thị Phương Anh 24A4043026 20%
3 Nguyễn Thị Thanh Thảo 24A4040492 20%
4 Phí Thị Thắm 24A4040379 20%
5 Trần Mai Anh 24A4043029 20%
Hà Nội, ngày 26 tháng 3 năm 2023
Trang 3LỜI CAM ĐOAN
Nhóm em đã đọc và hiểu về các hành vi vi phạm sự trung thực trong học thuật Nhóm em cam kết bằng danh dự cá nhân rằng bài tập lớn này do nhóm em tự thực hiện và không vi phạm yêu cầu về sự trung thực trong học thuật
Hà Nội, ngày 26 tháng 3 năm 2023 Học viên
Trang 4LỜI CẢM ƠN
Lời đầu tiên cho phép nhóm xin gửi lời cảm ơn chân thành nhất đến giảng viên Nguyễn Thanh Thụy Trong quá trình học tập một môn Cấu trúc dữ liệu và Giải thuật, nhóm chúng em đã được thầy quan tâm và giúp đỡ tận tình Sau 6 tuần học thì chúng
em đã tích lũy thêm được rất nhiều kiến thức để có thể có cái nhìn sâu sắc và hoàn thiện hơn về bộ môn này Thông qua bài tập lớn lần này, nhóm 14 muốn trình bày lại những gì mà chúng em đã tìm hiểu trong thời gian qua, áp dụng kiến thức thầy dạy vào một bài toán thực tế
Trong quá trình hoàn thành bài tập lớn lần này, chúng em đã có sự nỗ lực trong việc tìm hiểu, nghiên cứu các kiến thức để hoàn thiện bài tập lớn một cách tốt nhất trong khả năng của mình Nhóm em hi vọng sẽ nhận được những góp ý của thầy để bài tập lớn của chúng em được hoàn thiện hơn
Kính chúc thầy có thật nhiều sức khỏe và thành công trong con đường giảng dạy của mình, đặc biệt là đưa khoa Hệ thống thông tin quản lý ngày càng phát triển hơn
Hà Nội, ngày 26 tháng 3 năm 2023 Học viên
MỤC LỤC ii
Trang 5LỜI CAM ĐOAN i
LỜI CẢM ƠN ii
MỤC LỤC iii
DANH SÁCH CÁC HÌNH iv
DANH SÁCH CÁC BẢNG iv
LỜI MỞ ĐẦU 1
PHẦN I TỔNG QUAN 2
1.1 Danh sách liên kết đôi 2
1.2 Thuật toán Quick sort 2
PHẦN II Ý TƯỞNG – THUẬT TOÁN – MINH HỌA – ĐỘ PHỨC TẠP 3
2.1 Ý tưởng 3
2.2 Thuật toán 3
2.3 Minh họa thuật toán 4
2.4 Độ phức tạp của thuật toán 5
PHẦN III: ĐÁNH GIÁ CHUNG 6
3.1.Ưu điểm 6
3.2.Nhược điểm 6
KẾT LUẬN 7
TÀI LIỆU THAM KHẢO 8
DANH SÁCH CÁC HÌNH
Trang 6Hình 1: Cấu trúc danh sách liên kết đôi 2 Hình 2: Minh họa thuật toán Quick sort trong danh sách liên kết đơn 2 Hình 3: Minh họa thuật toán Quick sort trong danh sách liên kết đôi 5
DANH SÁCH CÁC BẢNG
Bảng 1: So sánh độ phức tạp theo thời gian của thuật toán Merge sort & Quick sort 6 Bảng 2: So sánh độ phức tạp trung bình của một số thuật toán sắp xếp 7
iv
Trang 7LỜI MỞ ĐẦU
Sắp xếp dãy số theo thứ tự tăng dần hay giảm dần là một bài toán sắp xếp đơn giản và cơ bản nhất đối với bất cứ ai học lập trình Nói theo cách khác, bài toán này chính là bài toán sắp xếp danh sách theo một chiều tăng dần hoặc giảm dần Bài toán sắp xếp dãy số là bài tập điển hình trong phần kiến thức về mảng một chiều Sắp xếp cũng là một kiến thức quan trọng thuộc phần giải thuật trong cấu trúc dữ liệu & giải thuật
Để tìm kiếm một cách nhanh chóng và thuật tiện, con người đã phát minh ra rất nhiều thuật toán để phục vụ cho nhu cầu đó Đáng kể nhất là thuật toán Quick sort -một thuật toán được sử dụng khá phổ biến trong ngôn ngữ lập trình
Chính vì thế, trong đề tài này, chúng em sẽ tìm hiểu về thuật toán sắp xếp danh sách liên kết đôi bằng thuật toán Quick sort
Trang 8PHẦN I TỔNG QUAN 1.1 Danh sách liên kết đôi
Mỗi node trong danh sách liên kết đôi gồm có previous pointer (con trỏ trước), data (giá trị) và next pointer (con trỏ sau)
Previous pointer trỏ tới phần tử đứng trước, next pointer trỏ tới phần tử phía sau
Hình 1: Cấu trúc danh sách liên kết đôi
1.2 Thuật toán Quick sort
Quick Sort là một thuật toán sử dụng cách thức chia để trị (Divide and Conquer algorithm) để sắp xếp các phần tử trong một mảng hoặc một danh sách.[1]
Dựa trên khái niệm phân vùng một mảng thành hai danh sách con xung quanh một phần tử chốt đã được chọn sao cho các phần tử trong danh sách con bên trái nhỏ hơn phần tử chốt và các phần tử trong danh sách con bên phải lớn hơn phần tử chốt.[2] Quá trình trên được lặp lại một cách đệ quy trên cả hai danh sách con cho đến khi toàn bộ danh sách được sắp xếp theo yêu cầu đề bài
Hình 2: Minh họa thuật toán Quick sort trong danh sách liên kết đơn
2
Trang 9PHẦN II Ý TƯỞNG – THUẬT TOÁN – MINH HỌA – ĐỘ PHỨC TẠP 2.1 Ý tưởng
Thuật toán Quick Sort có thể được áp dụng cho danh sách liên kết đôi theo cách tương tự như áp dụng cho mảng Ý tưởng cơ bản là chọn một phần tử chốt từ danh sách, phân vùng thành hai danh sách con và áp dụng đệ quy thuật toán Quick Sort cho các danh sách con ở hai bên của phần tử chốt [4]
Trong danh sách liên kết đôi, chúng ta có thể chọn bất kỳ nút nào làm phần tử chốt Giả sử chúng ta chọn phần tử đầu tiên của danh sách làm phần tử chốt Sau đó, ta
có thể duyệt qua danh sách từ đầu và hoán đổi vị trí các phần tử có giá trị nhỏ hơn phần tử chốt sang bên trái phần tử chốt, còn các phần tử có giá trị lớn hơn phần tử chốt sang bên phải phần tử chốt
Sau khi các danh sách con được sắp xếp, ta hợp nhất chúng theo thứ tự tăng dần hoặc giảm dần theo yêu cầu của bài toán [7]
2.2 Thuật toán
void quicksort(list &l)
{
list l1,l2;
node *tag, *p;
if(l.head==l.tail) return;
{
taolist(l1);
taolist(l2);
tag = l.head;
l.head = tag->next; // cập nhật lại lhead
tag->next = NULL; // cô lập tag
tag->prev =NULL;
}
while(l.head!=NULL)
{
p = l.head;
l.head = p->next;
p->next = NULL;
Trang 10if(p->data <= tag->data) addhead(l1,p->data); else addhead(l2,p->data);
}
quicksort(l1); // gọi đệ quy sắp xếp l1
quicksort(l2);
if(l1.head != NULL)
{
l.head = l1.head;
l1.tail->next = tag;
tag->prev = l1.tail;
}
else l.head=tag;
tag->next =l2.head;
if(l2.head !=NULL)
{
l.tail=l2.tail;
l2.head->prev =tag;
}
else l.tail = tag;
}
2.3 Minh họa thuật toán
4
Trang 11Hình 3: Minh họa thuật toán Quick sort trong danh sách liên kết đôi
2.4 Độ phức tạp của thuật toán
Độ phức tạp về thời gian của thuật toán Quick sort trong ngôn ngữ lập trình C trong các trường hợp khác nhau là:
Trường hợp tốt nhất: trường hợp này xảy ra khi phần tử chốt có giá trị trung vị, tức là số lượng phần tử có giá trị lớn hơn và nhỏ hơn giá trị của phần tử chốt gần như bằng nhau (hoặc bằng nhau) Điều này dẫn đến một phân vùng có cân bằng tốt và mỗi lệnh gọi đệ quy sẽ chia dãy làm đôi Độ phức tạp về thời gian cho trường hợp này
là O(n*log n) [4]
Trường hợp xấu nhất: Trường hợp này xảy ra khi phần tử chốt được chọn có giá trị nhỏ nhất hoặc lớn nhất trong dãy cần xử lý Trong trường hợp này, một dãy con không có phần tử nào và dãy con còn lại sẽ có (n-1) phần tử, trong đó n là tổng số phần tử của dãy Do đó, việc sắp xếp và phân vùng sẽ chỉ xảy ra ở một dãy con Độ phức tạp về thời gian cho trường hợp này sẽ là O(n²) [4]
Trường hợp trung bình: Trường hợp này xảy ra khi phần tử chốt không phải là phần tử có giá trị trung vị hoặc có giá trị lớn nhất hay nhỏ nhất của dãy hiện hành Độ phức tạp về thời gian cho trường hợp này sẽ là O(n*log n) [4]
Trang 12PHẦN III: ĐÁNH GIÁ CHUNG 3.1 Ưu điểm
Là một thuật toán chia để trị giúp giải quyết vấn đề dễ dàng hơn
Có chi phí hoạt động thấp vì chỉ yêu cầu một lượng nhỏ bộ nhớ để hoạt động
Có nhiều cách để lựa chọn phần tử chốt, giảm thiểu trường hợp xấu nhất xảy ra Thời gian thực hiện nhanh hơn so với một số thuật toán khác
O(nlogn)
Bảng 1: So sánh độ phức tạp theo thời gian của thuật toán Merge sort & Quick sort
3.2.Nhược điểm
Là thuật toán không ổn định
Phụ thuộc vào phần tử chốt
6
Trang 13KẾT LUẬN
Thuật toán sắp
xếp
Độ phức tạp (trung
bình) Bubble sort O( n2) Selection sort O( n2) Insertion sort O( n2) Merge sort O(nlogn) Quick sort O(nlogn) Heap sort O(nlogn) Shell sort O( n4/ 3
) Bảng 2: So sánh độ phức tạp trung bình của một số thuật toán sắp xếp Như vậy, việc sử dụng thuật toán Quick sort trong danh sách liên kết đôi là một phương pháp hiệu quả vì thời gian trung bình để giải bài toán của thuật toán này là O(nlogn), ít hơn đa số các thuật toán khác (như bảng ở trên) Tuy nhiên, việc sắp xếp danh sách liên kết đôi bằng thuật toán Quick sort lại gây ra một nhược điểm là có thể gây ra trường hợp xấu nhất, làm tốn thời gian, giảm hiệu suất nếu không chọn phần tử chốt một cách hợp lý Nhìn chung thì thuật toán Quick sort vẫn là một thuật toán giúp tăng hiệu quả sắp xếp trong danh sách liên kết
Trang 14TÀI LIỆU THAM KHẢO
[1]}]]David Xuân, “QuickSort trên danh sách liên kết kép – Doubly Linked List,” 8
10 2020 [Trực tuyến] Available: https://cafedev.vn/ctdl-quicksort-tren-danh-sach-lien-ket-kep-doubly-linked-list/ [Đã truy câ ™p 20 3 2023]
[2] Dương Anh Đức, “Thuật toán Quick Sort là gì? Giới thiệu lập trình chi tiết nhất,” 26 5 2022 [Trực tuyến] Available: https://teky.edu.vn/blog/thuat-toan-quick-sort/#Do_phuc_tap_cua_thuat_toan_sap_xep_nhanh [Đã truy câ ™p 20 2 2023]
[3] Đỗ Xuân Lôi, Cấu trúc dữ liệu và giải thuật, Hà Nội: Nhà xuất bản Đại học Quốc gia Hà Nội, 2010
[4] Lê Khiêm, “Thuật toán sắp xếp trong C++,” 4 2 2022 [Trực tuyến] Available: https://topdev.vn/blog/thuat-toan-sap-xep-trong-c/?
fbclid=IwAR3hEfU5MO_F8EL_Mbp7YkCBDqKHsevIl_9QeWWw409Nhayw ENP86hQdUBU [Đã truy câ ™p 20 3 2023]
[5] Nguyễn Đức Nghĩa, Giáo trình cấu trúc dữ liệu và giải thuật, Hà Nội: Nhà xuất bản Bách khoa - Hà Nội, 2022
[6] Phạm Văn Ất, Giáo trình Kỹ thuật lập trình C Căn bản & Nâng cao, Hà Nội: Nhà xuất bản Hồng Đức, 2009
[7] R Sedgewick, "QuickSort on Doubly Linked List," 16 11 2020 [Online] Available: https://www.codesdope.com/blog/article/quicksort-on-doubly-linked-
list/?fbclid=IwAR2C91lw0eO-LbOXSRRpq3PRq8ksHWL48G78qMWHACSvEGD4sDU4PlcUFUY
[Accessed 20 3 2023]
[8] C.-K Shene, "A Comparative Study Of Linked List Sorting Algorithms," Michigan Technological University, Michigan, 2022
8