Thuật Toán Sắp Xếp Nhanh (Quick Sort) - Viblo
Có thể bạn quan tâm
I. Làm quen với thuật toán
So với thuật toán sắp xếp nổi bọt (bubble sort) thì thuật toán sắp xếp nhanh có tốc độ nhanh hơn. Thay vì đi theo sắp xếp từng cặp như bubble sort, chúng ta có thể chia dữ liệu ra thành 22 danh sách, rồi so sánh từng phần tử của danh sách với một phần tử được chọn (gọi là phần tử chốt) và mục đích của chúng ta là đưa phần tử chốt về đúng vị trí của nó.
II. Miêu tả thuật toán
Chắc hẳn bạn vẫn còn khá mông lung với thuật toán, để giúp bạn hiểu rõ hơn, chúng ta hãy cùng đến với một trò chơi "hành quân" sau:
Xét một dãy số như sau:
6,1,2,7,9,3,4,5,10,86, 1, 2, 7, 9, 3, 4, 5, 10, 8
Yêu cầu là sắp xếp dãy trên theo thứ tự không giảm từ trái qua phải.
Chọn phần tử chốt là số 6, xét hai "quân lính" là quân lính AA và quân lính BB lần lượt đặt ở hai đầu của dãy số (quân AA ở vị trí đầu tiên bên trái, quân BB ở vị trí cuối cùng bên phải). Luật hành quân như sau: quân BB đi trước, bắt đầu di chuyển về bên trái, đến khi gặp được phần tử có giá trị nhỏ hơn giá trị của phần tử chốt thì dừng lại, ở đây quân BB dừng ở vị trí của số 55; Tiếp theo đến lượt quần AA, bắt đầu di chuyển về bên phải, đến khi gặp được phần từ có giá trị lớn hơn giá trị của phần tử chốt thì dừng lại, ở đây quân AA dừng ở vị trí số 77. Lúc này ta đổi chỗ 22 số ở vị trí của quân AA và BB cho nhau, sau đó hai quân AA và BB trở về vị trí như lúc đầu, ta thu được dãy số sau:
6,1,2,5,9,3,4,7,10,86, 1, 2, 5, 9, 3, 4, 7, 10, 8
Tiếp tục cuộc hành quân như trên, lượt này ta sẽ cần đổi chỗ hai số 44 và 99 cho nhau, ta được dãy số:
6,1,2,5,4,3,9,7,10,86, 1, 2, 5, 4, 3, 9, 7, 10, 8
Đến với lượt hành quân tiếp theo, ta thấy quân BB sẽ dừng lại ở vị trí của số 33, tuy nhiên quân AA chưa tìm được số nào lớn hơn 66 đã "đụng mặt" quân B, như vậy ta coi lượt hành quân này là thất bại, và ta tiến hành đổi chỗ số 33 (số mà quân BB đang dừng lại) với phần tử chốt là số 66. Ta thu được:
3,1,2,5,4,6,9,7,10,83, 1, 2, 5, 4, 6, 9, 7, 10, 8
Lúc này, chúng ta hãy quan sát phần tử chốt (số 66): sau loạt hành quân đầu tiền thì tất cả những phần tử nằm bên trái phần tử chốt đều nhỏ hơn nó, và tất cả những phần tử nằm bên phải phần tử chốt đều lớn hơn nó. Như vậy ta đã đưa số 66 về đúng vị trí của nó.
Tiếp theo dãy được chia thành 22 dãy nhỏ hơn là dãy bên trái số 66 và dãy bên phải số 66. Ta tiếp tục thực hiện luật hành quân như trên đối với hai dãy này và sẽ thu được thêm các phần tử chốt khác ở đúng vị trí và xuất hiện thêm các dãy con độ dài ngắn hơn. Thực hiện đến cuối ta thu được dãy có thứ tự như mong muốn.
III. Thuật toán tham khảo
- Thuật toán sắp xếp nhanh C++:
- Thuật toán sắp xếp nhanh Java:
- Thuật toán sắp xếp nhanh PHP:
IV. Những điều lưu ý về thuật toán
1. Phần tử chốt.
Sau khi hiểu về thuật toán, có lẽ bạn sẽ có một nghi vấn nhỏ nảy lên trong đầu: Tại sao chọn phần tử chốt là phần tử đầu tiên bên trái? Và cách chọn phần tử chốt có ảnh hưởng đến độ nhanh chậm của sắp xếp hay không? Thực tế thì kỹ thuật chọn phần tử chốt ảnh hưởng khá lớn đến thuật toán, bởi chúng ta có khả năng bị rơi vào các vòng lặp vô hạn. Một số cách chọn phần tử chốt để bạn tham khảo:
- Chọn phần tử đứng đầu hoặc đứng cuối làm phần tử chốt.
- Chọn phần tử đứng giữa danh sách làm phần tử chốt.
- Chọn phần tử trung vị trong 3 phần tử đứng đầu, đứng giữa và đứng cuối làm phần tử chốt.
- Chọn phần tử ngẫu nhiên làm phần tử chốt. (Cách này có thể dẫn đến khả năng rơi vào các trường hợp đặc biệt)
2. Ưu điểm
- Tốc độ sắp xếp nhanh.
- Được sử dụng trong nhiều thư viện của các ngôn ngữ như C++, Java, ...
3. Nhược điểm
- Phụ thuộc vào cách chọn phần tử chốt.
- Không ổn định.
4. Nhận xét
So với sắp xếp nổi bọt thì sắp xếp nhanh mỗi lần đổi chỗ mang tính nhảy vọt. Từng lượt ta chọn một phần tử chốt, đem những số nhỏ hơn nó đặt bên trái nó, những số lớn hơn nó đặt bên phải phải. Dẫn đến số lượt đổi chỗ được ít hơn so với sự đổi chỗ từng cặp của sắp xếp nổi bọt. Tuy nhiên vào tình huống xấu nhất (việc chọn phần tử chốt chưa đủ tốt) có thể khiến độ phức tạp thuật toán là O(N2)O(N^2). Do tính không ổn định của quick sort nên nó có độ phức tạp trung bình là O(N.logN)O(N.logN).
V. Tài liệu tham khảo
- https://vi.wikipedia.org/wiki/S%E1%BA%AFp_x%E1%BA%BFp_nhanh
- https://en.wikipedia.org/wiki/Quicksort
©️ Tác giả: Lê Ngọc Hoa từ Viblo
Từ khóa » Cách Dùng Hàm Qsort
-
Hàm Qsort() Trong C / C++
-
Hàm Qsort() Trong C
-
Hàm Qsort() Trong C | Thư Viện C Chuẩn
-
21 [Bài Tập C ( Mảng)]. Cách Sử Dụng Hàm QSort Trong Thư Viện ...
-
C++ Quicksort: Cách Khởi Tạo Và Sử Dụng - Seth Phát Blog
-
Thuật Toán Quick Sort - Sắp Xếp Nhanh Cài đặt Với C/C++
-
Hàm Qsort() Trong C - HKT SOFT
-
Cách Sử Dụng Hàm Qsort Với Kiểu Số Thực Và Chuỗi - Cộng đồng C Việt
-
Hàm Qsort() Trong C - Vay Tiền Online Bằng CMND
-
Hàm Qsort() Trong C - Thương Mại Điện Tử
-
Quick Sort — Giải Thuật Lập Trình - STDIO
-
C ++ Qsort () - Thư Viện Chuẩn C ++
-
Thuật Toán Sắp Xếp Trong C++ | TopDev
-
Sắp Xếp Mảng Trong C