LỜI NÓI ĐẦUTrong thời đại số hóa và công nghệ thông tin hiện nay, việc nắm vững và hiểu sâu về cácthuật toán sắp xếp không chỉ là một phần quan trọng của kiến thức trong lĩnh vực khoahọc
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 LỚN Học phần: CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT
Đề tài: Thuật toán sắp xếp nhanh - QuickSort
Giáo viên hướng dẫn: Thầy Nguyễn Thanh Thụy Sinh viên thực hiên: Nhóm 05
Lớp: K25CNTTA
Hà Nội, Tháng 11 năm 2023
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 LỚN
Học phần: CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT
Đề tài: Thuật toán sắp xếp nhanh - QuickSort
Giáo viên hướng dẫn: Thầy Nguyễn Thanh Thụy
Sinh viên thực hiên: Nhóm 05
Lớp: K25CNTTA
1 Trần Thị Huyền Châm 25A4041527 20%
Trang 3MỤC LỤC
LỜI NÓI ĐẦU 1
I Lịch sử hình thành của thuật toán Sắp xếp nhanh - QuickSort 2
II Ý tưởng thuật toán 3
1 Ý tưởng 3
2 Cách chọn phần tử làm chốt – pivot 4
III Thuật toán 4
IV Cài đặt thuật toán 4
V Minh họa thuật toán 6
VI Độ phức tạp 8
1 Độ phức tạp của thuật toán QuickSort 8
1.1 Trường hợp tốt nhất 8
1.2 Trường hợp trung bình 8
1.3 Trường hợp xấu nhất 9
2 So sánh độ phức tạp với một số thuật toán 9
VII Tổng kết 10
1 Ưu điểm và nhược điểm của thuật toán Sắp xếp nhanh 10
1.1 Ưu điểm 10
1.2 Nhược điểm 10
2 Kết luận 10
TÀI LIỆU THAM KHẢO 12
Trang 4DANH MỤC HÌNH ẢNH
Hình 1 - Tác giả Hình 2 - Minh họa thuật toán
Trang 5LỜI NÓI ĐẦU
Trong thời đại số hóa và công nghệ thông tin hiện nay, việc nắm vững và hiểu sâu về cácthuật toán sắp xếp không chỉ là một phần quan trọng của kiến thức trong lĩnh vực khoahọc máy tính và lập trình mà còn là chìa khóa mở cánh cửa cho sự thành công trong việc
xử lý dữ liệu lớn và tối ưu hóa hiệu suất hệ thống Bên cạnh đó, việc hiểu biết thêm vềthuật toán cũng sẽ trở thành công cụ giúp chúng ta trong quá trình tìm kiếm việc làm.Với bài tập lớn này, chúng ta sẽ đi vào tìm hiểu một trong những thuật toán sắp xếp phổbiến và mạnh mẽ nhất – thuật toán Sắp xếp nhanh hay còn gọi là QuickSort Bài tập lớnnày sẽ đi vào việc tìm hiểu về nguồn gốc hình thành của thuật toán Sắp xếp nhanh, ýtưởng và các bước để chúng ta thực hiện thuật toán đồng thời cũng đưa ra một cách đểxây dựng thuật toán này trên ngôn ngữ lập trình C++ và minh họa các bước hoạt động củathuật toán
Như vậy, qua quá trình tìm hiểu về thuật toán Sắp xếp nhanh, chúng ta sẽ hiểu rõ hơn về
cơ sở lý thuyết và từ đó tự tìm hiểu cách ứng dụng nó để nâng cao khả năng học hỏi vàsáng tạo của bản thân, từng bước biến thuật toán thành công cụ hữu ích của mình trongcông việc
1
Trang 6I Lịch sử hình thành của thuật toán Sắp xếp nhanh - QuickSort
QuickSort là một thuật toán sắp xếp (Sorting Algorithm) trong khoa học máy tính đượcphát triển bởi một nhà khoa học người Anh là Tony Hoare Khi đang học tại Đại họcQuốc gia Moscow, Tony Hoare nhận được một đề nghị làm việc từ Viện Vật lý Quốc gia(NPL) để tham gia dự án mới về dịch máy từ tiếng Nga sang tiếng Anh Tuy nhiên, vì từđiển được lưu trữ trên băng từ, ông cần phải sắp xếp các từ trong câu theo thứ tự chữ cáitrước khi dịch
Hoare đã nghĩ ra hai phương pháp để giải quyết vấn đề này Phương pháp đầu tiên sẽ mấtthời gian tỷ lệ với bình phương độ dài của câu Phương pháp thứ hai sau này đã biếnthành thuật toán QuickSort Vào thời điểm đó, ông chỉ biết một ngôn ngữ lập trình làMercury Autocode Thật không may, ông không thể viết thành công QuickSort bằngMercury Autocode
Hình 1 - Tác giả
(Nguồn: izquotes.com)
Năm 1961, Hoare tham gia một khóa học về Algol 60 tại Brighton Algol 60 cho phép đệquy (khả năng của một thủ tục gọi chính nó) Trong khóa học này, Hoare đã lập trình mộtthuật toán sắp xếp siêu nhanh được biết đến ngày nay với tên gọi QuickSort Bài báo đầutiên về QuickSort của ông cũng được công bố vào năm 1961, và một bài báo khác đượcxuất bản vào năm 1962
Trang 7II Ý tưởng thuật toán
1 Ý tưởng
Thuật toán QuickSort là một thuật toán sắp xếp dãy số trong máy tính dựa trên nguyên tắcchia để trị Ý tưởng cơ bản của thuật toán QuickSort là chia mảng dữ liệu thành các phầnnhỏ hơn, sau đó sắp xếp từng phần nhỏ này và kết hợp chúng ta để tạo ra một mảng đượcsắp xếp Quá trình chia sẻ và kết hợp quy trình đệ quy cho đến khi sắp xếp mảng hoànchỉnh
Cụ thể, trình diễn QuickSort như sau:
Lựa chọn một phần tử từ mảng được gọi là “pivot” Phần tử này sẽ được sử dụng để phânchia mảng thành hai phần: một phần chứa tất cả các phần nhỏ hơn hoặc bằng pivot và mộtphần chứa tất cả các phần tử lớn hơn pivot
Di chuyển các phần tử trong mảng sao cho các phần tử nhỏ hơn trục nằm bên trái của trục
và các phần tử lớn hơn trục nằm bên phải của trục Điều này thường được thực hiện thôngqua một quá trình gọi là “partition” (phân hoạch)
Đệ quy áp dụng thuật toán QuickSort cho cả hai phần của mảng: phần bên trái của pivot
và phần bên phải của pivot
Quá trình đệ quy sẽ tiếp tục cho đến khi mỗi phần tử chỉ còn một phần tử hoặc không cóphần tử nào
Khi tất cả các phần tử đã được sắp xếp, mảng gốc cũng đã được sắp xếp
Hình 2 - Minh họa thuật toán
(Nguồn: Teky)
3
Trang 82 Cách chọn phần tử làm chốt – pivot
Chọn phần tử đầu tiên của mảng
Chọn phần tử cuối cùng của mảng
Chọn phần tử giữa mảng
Chọn ngẫu nhiên phần tử trong mảng
III Thuật toán
Trong thuật toán QuickSort, việc phân hoạch dựa trên các bước sau:
Bước 1 - Chọn tùy ý một phần tử a[k] trong dãy làm phần tử chốt
(left ≤ k ≤ right), xác định hai biến i và j lần lượt bằng phần tử đầu tiên và cuối cùng củadanh sách:
Pivot = a[k]; i = left; j = right
Bước 2 – Phát hiện và hiệu chỉnh cặp phần tử a[i], a[j] nằm sai chỗ:
o Bước 2a – Trong khi (a[i] < pivot) thì i++;
o Bước 2b – Trong khi (a[j] > pivot) thì j ;
o Bước 2c – Nếu i < j ta đổi chỗ a[i], a[j];
Bước 3 – Nếu i < j, lặp lại Bước 2 Ngược lại: Dừng
IV Cài đặt thuật toán
Dưới đây là thuật toán Sắp xếp nhanh – QuickSort được biểu diễn bằng ngôn ngữ lập trình C++:
void quickSort(int a[], int l, int r){
int p = a[(l+r)/2]; //Xac dinh phan tu chot la phan tu nam giua trong day
Trang 10Cho dãy số a: 12 2 8 5 1 6 4 15
Sắp xếp dãy a theo thứ tự tăng dần bằng thuật toán QuickSort như sau:
0 1 2 3 4 5 6 7
Trang 11Ta có n = 8, tiến hành phân hoạch đoạn left = 0, right = 7, pivot = a[(0+7)/2] = 5.Gán i = left = 0, j = right = 7
Duyệt i từ left đến right và so sánh i với pivot, nếu i < pivot thì tiếp tục duyệt và ngược lạitạm dừng i Do đó i dừng lại tại vị trí thứ 0 do a[0] = 12 > pivot
Duyệt j từ right đến left và so sánh j với pivot, nếu j > pivot thì tiếp tục duyệt và ngược lạitạm dừng j Do đó j dừng lại tại vị trí thứ 6 do a[6] = 4 < pivot
Hoán đổi cặp phần tử a[i] và a[j], tăng i và giảm j
Trang 12Tiếp tục duyệt i và j Ta thấy i dừng lại tại vị trí 2 do a[i] = 8 > pivot và j dừng lại tại vị trí
4 do a[j] = 1 < pivot Hoán đổi cặp phần tử a[i] và a[j], tăng i và giảm j
0 1 2 3 4 5 6 7
0 1 2 3 4 5 6 7
Trang 13Ta thấy i, j tiếp tục duyệt cho đến khi gặp nhau tại vị trí 3 và dừng lại do a[i] = 3 khôngnhỏ hơn pivot và a[j] = 3 không lớn hơn pivot Hoán đổi cặp phần tử a[i] và a[j], tăng i vàgiảm j.
0 1 2 3 4 5 6 7
0 1 2 3 4 5 6 7
9
Trang 14Lúc này, do i > j nên tạm dừng phân hoạch và i =4, j = 2 Xét điều kiện rồi gọi đệ quyphần hoạch lần lượt 2 dãy con a = a[left]…a[j] và a = a[i]…a[right] như sau:1 2
Phân hoạch dãy bên trái, chọn 2 làm pivot, thực hiện như trên:
0 1 2 3 4 5 6 7
0 1 2 3 4 5 6 7
Trang 15Do 2 dãy con bên phải giá trị 2 chỉ còn 1 phần tử nên coi như đã được sắp xếp.
Phân hoạch dãy bên phải, chọn 6 làm pivot và tiến hành tuần tự như trên cho đến khi tất
cả phần tử đã được sắp xếp thì kết thúc chương trình:
0 1 2 3 4 5 6 7
11
Trang 160 1 2 3 4 5 6 7
Trang 170 1 2 3 4 5 6 7
13
Trang 18Như vậy, sau quá trình sắp xếp ta thu được dãy sắp xếp tăng dần như trên.
1.2 Trường hợp trung bình
Trường hợp này gần giống với trường hợp tốt nhất, cụ thể như sau: Trong trường hợptrung bình của thuật toán QuickSort, mảng được phân chia thành hai phần gần bằng nhausau mỗi lần phân đoạn Tuy nhiên, mảng không được chia đều mà phụ thuộc vào sự lựachọn của pivot Sự lựa chọn của pivot có thể là ngẫu nhiên hoặc dựa trên một chiến lượcnhất định Trong trường hợp này, thuật toán QuickSort trung bình có độ phức tạp thờigian là O(n*log(n))
1.3 Trường hợp xấu nhất
Trong trường hợp xấu nhất của thuật toán QuickSort, mảng sẽ được phân chia thành haiphần không cân đối sau mỗi lần phân đoạn Khi điều này xảy ra, thuật toán có độ phức tạpthời gian tệ nhất, là O(n2), với n là kích thước của mảng ban đầu Trường hợp xấu nhấtxảy ra khi pivot được chọn một cách xấu, ví dụ như là phần tử nhỏ nhất hoặc lớn nhấttrong mảng
2 So sánh độ phức tạp với một số thuật toán
Thuật toán sắp xếp
Độ phức tạp thời gianTrường hợp tốt
nhất
Trường hợp trung bình Trường hợp xấu nhất
Simple Sort
Trang 19(Selection,
Insertion,
Bubble, …)
O(n) /O(n) /O(n)
O(n2) O(n )2
Shell Sort O(nlogn) O(n4/3) O(nlog n)2
Heap Sort O(nlogn) O(nlogn) O(nlogn)
Thuật toán Quick Sort có cấu trúc đơn giản, dễ hiểu và dễ triển khai trong các chươngtrình lập trình Vì vậy, việc cài đặt và sử dụng thuật toán Quick Sort dễ dàng hơn so vớimột số thuật toán sắp xếp khác
Đặc biệt Quick Sort có khả năng sắp xếp trong chính nó, không cần sử dụng một mảngphụ để lưu trữ các giá trị trung gian trong quá trình sắp xếp Điều này đã giúp giảm thiểuviệc sử dụng bộ nhớ và tăng hiệu suất
Thuật toán Quick Sort có thể được tùy biến để phù hợp với nhiều tình huống khác nhau,bằng cách thay đổi cách chọn pivot hoặc cách xử lý các phần tử bị trùng lặp
15
Trang 20Thuật toán Quick Sort hoạt động tốt với các tập dữ liệu nhỏ, đặc biệt là khi sử dụng phiênbản đơn giản của thuật toán.
tử có cùng khóa hoặc giống nhau khi chúng ta sắp xếp vì ta chỉ hoán đổi chúng dựa trên
vị trí của pivot mà không xem xét đến vị trí ban đầu của chúng
2 Kết luận
Trong bài tập lớn này, chúng ta đã tìm hiểu về thuật toán Quicksort - một trong nhữngthuật toán sắp xếp hiệu quả và phổ biến nhất trong lĩnh vực khoa học máy tính Quicksortkhông chỉ nổi tiếng với hiệu suất cao của mình, mà còn với tính linh hoạt và dễ triển khai.Chúng ta đã xem xét cách thuật toán hoạt động, từ việc chia mảng thành các phần nhỏ đếnquá trình sắp xếp các phần này một cách đệ quy
Quicksort sử dụng chiến lược chia để trị, tận dụng việc chọn phần tử chốt (pivot) để đảmbảo rằng các phần tử nhỏ hơn pivot được đặt bên trái và các phần tử lớn hơn pivot đượcđặt bên phải Điều này tạo ra một cách tiếp cận hiệu quả để sắp xếp mảng một cách nhanhchóng
Tuy nhiên, cũng cần lưu ý rằng Quicksort có thể trở nên không hiệu quả trong trường hợpxấu nhất khi mảng đã sắp xếp hoặc gần sắp xếp Điều này đặt ra thách thức trong việcchọn pivot và yêu cầu sự cân nhắc trong triển khai
Tổng kết, việc nắm vững Quicksort không chỉ mở ra cánh cửa cho việc hiểu sâu về sắpxếp mảng, mà còn giúp chúng ta phát triển khả năng giải quyết vấn đề và tư duy lập trình.Quicksort không chỉ là một công cụ quan trọng trong lĩnh vực khoa học máy tính mà còn
là một khía cạnh quan trọng của sự phát triển cá nhân trong ngành công nghiệp này
Trang 21TÀI LIỆU THAM KHẢO
1
Anon., 2008 stanford [Online]
Available at: hoare/quicksort.html?fbclid=IwAR1_U8ltIGpOo4SAEGo6VVEOuDsD88A2EqgNG-w5oRQBjzyx4GMAI38yxfs
https://cs.stanford.edu/people/eroberts/courses/soco/projects/2008-09/tony-[Accessed 7 11 2023]
2 GeeksforGeeks, 2023 geeksforgeeks [Online]
Available at: https://www.geeksforgeeks.org/quick-sort/?
fbclid=IwAR1YCx3g39OR0Gn9_MeGv6Hi76TEt8JZ11sZO7v6hrQDejioLyTVU302I48[Accessed 5 11 2023]
3 Thuy, N T., không ngày tháng google doc [Trực tuyến]
Available at:
https://docs.google.com/presentation/d/1_zevH2Ur8aElDGqFTiEfciUrCtqCAAk1/edit#slide=id.p140
[Đã truy câ –p 7 11 2023]
17