I. Các khái niệm và tính chất cơ bản
4. Các ứng dụng
4.4.3 Thuật toán sắp xếp nhanh
Sắp xếp 1 danh sách có nhiều thuật toán, mỗi thuật toán đều có những ưu nhược điểm. Trong các thuật toán sắp xếp thì thuật sắp xếp nhanh (Quick sort) tỏ ra có nhiều ưu điểm được sử dụng phổ biến và rất hiệu quả. Nguyên tắc của thuật toán này có tính đệ quy có thể sử dụng cây nhị phân để mô tả thuật toán này. Thuật toán có thể được mô tả tóm tắt như sau:
Ví dụ để sắp xếp danh sách a1, a2, ..., an thuật toán bắt đầu bằng việc lấy ngẫu nhiên 1 phần tử làm chốt nhưng thường thì phần tử đầu tiên được chọn làm chốt. Như danh sách trên ta chọn a1 làm chốt khi đó danh sách được phân đoạn thành 2 danh sách con, một danh sách con gồm các phần tử nhỏ hơn a1 theo thứ tự xuất hiện, còn danh sách con khác gồm các phần tử lớn hơn a1 cũng theo thứ tự xuất hiện. Sau khi đã có hai danh sách con thì a1 được đặt vào sau cùng của danh sách con gồm các phần tử nhỏ hơn a1, như vậy sau a1 là danh sách con gồm các phần tử lớn hơn a1. Thủ tục này được lặp lại một cách đệ quy cho mỗi danh sách con cho tới khi nào mỗi danh sách con chỉ chứa một phần tử theo thứ tự xuất hiện của nó. Với kết quả này ta được một danh sách đã được sắp xếp. Ví dụ cho danh sách: 3, 5, 7, 8, 1, 9, 2, 6;
Có thể dùng cây nhị phân biểu diễn thuật toán sắp xếp nhanh để sắp xếp danh sách này như hình 1.9 68 3, 5, 7, 8, 1, 9, 2, 4, 6 1, 2, 3 5, 7, 8, 9, 4, 6 1 2, 3 4, 5 7, 8, 9, 6 2 3 4 5 6, 7 8, 9
Hình 1.9
Danh sách lúc chưa sắp xếp là gốc, danh sách được sắp xếp là danh sách mà mỗi phần tử của nó là lá của cây.
Chương trình thể hiện thuật toán sắp xếp nhanh như sau: Uses Crt;
const
Max = 10; type
List = array[1..Max] of Integer; var
Data: List; I: Integer;
procedure QuickSort(var A: List; Lo, Hi: Integer); procedure Sort(l, r: Integer);
var i, j, x, y: integer; begin i := l; j := r; x := a[(l+r) DIV 2]; repeat while a[i] < x do i := i + 1; while x < a[j] do j := j - 1; if i <= j then begin
i := i + 1; j := j - 1; end; until i > j; if l < j then Sort(l, j); if i < r then Sort(i, r); end; Begin {QuickSort}; Sort(Lo,Hi); End; Begin {QSort}
{ Khởi tạo ngẫu nhiên 10 phần tử } Randomize;
for i := 1 to Max do Data[i] := Random(3000); Writeln; {Sắp xếp các phần tử bằng Quick Sort} QuickSort(Data, 1, Max); Writeln; for i := 1 to 10 do Write(Data[i]:8); End.
Người ta đã chỉ ra rằng độ phức tạp của thuật toán là O(nlog2n)