Quick Sort
Ý tưởng:
CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT 1
Giải thuật QuickSort sắp xếp dãy a1, a2 ..., aN dựa trên
việc phân hoạch dãy ban đầu thành 3 phần :
• Phần 1: Gồm các phần tử có giá trị bé hơn
x
• Phần 2: Gồm các phần tử có giá trị bằng x
• Phần 3: Gồm các phần tử có giá trị lớn
hơn x
với x là giá trị của một phần tử tùy ý trong dãy ban
đầu.
1
Quick Sort - Ý Tưởng
Sau khi thực hiện phân hoạch, dãy ban đầu được phân thành
3 đoạn:
CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT 1
• 1. ak ≤ x , với k = 1 .. j
• 2. ak = x , với k = j+1 .. i-1
• 3. ak ≥ x , với k = i..N
2
CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT 1
Quick Sort – Ý Tưởng
Đoạn thứ 2 đã có thứ tự.
Nếu các đoạn 1 và 3 chỉ có 1 phần tử : đã có thứ tự
khi đó dãy con ban đầu đã được sắp.
3
Quick Sort – Ý Tưởng
CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT 1
Đoạn thứ 2 đã có thứ tự.
Nếu các đoạn 1 và 3 có nhiều hơn 1 phần tử thì dãy
ban đầu chỉ có thứ tự khi các đoạn 1, 3 được sắp.
Để sắp xếp các đoạn 1 và 3, ta lần lượt tiến hành việc
phân hoạch từng dãy con theo cùng phương pháp
phân hoạch dãy ban đầu vừa trình bày …
4
CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT 1
Giải Thuật Quick Sort
IV. Quick sort
Đây là giả thuật sắp xếp nhanh, chỉ tốn O(nlogn). Cài đặt
của giả thuật tương đối phức tạp. Chúng ta cần chú ý đến:
Pivot: ta gọi là chốt
Partition: Gọi là điểm phân hoạch
Đối với giải thauật này, chúng ta xem 1 mảng 1 phần tử
hay mảng có tất cả phần tử giống nhau là một mảng có thứ
tự. Ta sẽ chi mảng thành 2 mảng con: Trái và phải. Sắp xếp
2 mảng con, và cứ như thế cho đến khi mảng còn 1 phần
tử. Nếu mảng Trái đã có thứ tự và mảng phải cũng có thứ
tự thì mảng của chúng ta đã là mảng có thứ tự.
5
CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT 1
A = {59, 31, 12, 33, 27, 97, 91, 19, 18, 63 }
Bước 1: Tìm chốt: Chốt là phần tử lớn nhất trong 2 phần tử
khác nhau đầu tiên của mảng. Nếu mảng có 1 phần tử tất cả
phần tử bằng nhau sẽ không có chốt:
Chốt của mảng trên la 59 (vị trí 0).
VD:
+ 1, 1, 5, 3, 2 -> chốt sẽ là 5
+ 5, 5, 5, 3, 1, 2, 3 -> chốt là 5
+ 6 -> không có chốt
+ 7, 7, 7, 7 -> không có chốt
6
CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT 1
Bước 2: Tìm điểm phân hoạch:
+ Dùng 2 cờ: L (trái) và R (Phải)
+ L chạy từ trái qua, dừng lại khi gặp phần tử >= pivot
+ R chạy từ phải qua, dừng lại khi gặp phần tử < pivot
+ Tại điểm dùng: Nếu L < R : Chúng ta sẽ swap A[L] và
A[R]
+ Dừng lại khi L > R
+ Partition sẽ là L. Đây sẽ là chỉ số đầu tiên của mảng bên
phải
7
CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT 1
VD: với mảng A = {59, 31, 12, 33, 27, 97, 91, 19, 18, 63 }
PivotLey = 59
L = 0, R = 9:
b1. L dừng lại tại vị trí 0: vì A[L] >= pivot, R dừng lại tại vị
trí 8, vì A[R] = 18 < pivot.
Swap: 18, 31, 12, 33, 27, 97, 91, 19, 59, 63
b2, tiếp tục cho đến khi L > R
Bước 3: Lặp lại như thế (Dùng đệ qui)
8
Giải Thuật Quick Sort
Bước 1: Nếu left ≥ right //dãy có ít hơn 2 phần tử
Kết thúc;
//dãy đã được sắp xếp
CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT 1
Bước 2: Phân hoạch dãy aleft … aright thành các đoạn:
aleft.. aj, aj+1.. ai-1, ai.. aright
Đoạn 1 ≤ x
Đoạn 2: aj+1.. ai-1 = x
Đoạn 3: ai.. aright ≥ x
Bước 3: Sắp xếp đoạn 1: aleft.. aj
Bước 4: Sắp xếp đoạn 3: ai.. aright
9
Giải Thuật Quick Sort
Bước 1 : Chọn tùy ý một phần tử a[k] trong dãy là
giá trị mốc ( l ≤ k ≤ r):
x = a[k]; i = l; j = r;
CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT 1
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ỗ :
Bước 2a : Trong khi (a[i]
Bước 2b : Trong khi (a[j]>x) j--;
Bước 2c : Nếu i< j Swap(a[i],a[j]);
Bước 3 : Nếu i < j:
Lặp lại Bước 2.
Ngược lại: Dừng
10
Quick Sort – Ví Dụ
CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT 1
Cho dãy số a:
12
2 8
5
1
6
Phân hoạch đoạn l =0, r = 7:
12
2
8
5
l=0
4
15
x = a[3] = 5
1
6
4
15
r=7
11
Quick Sort – Ví Dụ
4
2
8
5
1
6
i=0
j=6
CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT 1
l=0
4
l=0
12
2
8
i=1
i=2
5
12
1
6
12
j=3
j=4
j=5
15
r=7
15
r=7
Quick Sort – Ví Dụ
CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT 1
Phân hoạch đoạn l = 0, r = 2:
4
l=0
i=0
2
1
5
8
r =3
j=2
13
6
12
15
Quick Sort – Ví Dụ
Phân hoạch đoạn l =4, r = 7:
CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT 1
1
2
4
5
8
l=4
i=4
1
2
4
5
6
i=4
l=4
14
6
12
15
r =7
j=6
j=6
j=7
8
12
15
r =7
Quick Sort – Ví Dụ
CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT 1
Phân hoạch đoạn l =6, r = 7:
1
2
4
5
6
15
8
12
15
CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT 1
Quick Sort
void QuickSort(int a[], int left, int right)
{ int i, j, x;
x = a[(left+right)/2];
i = left; j = right;
do
{
while(a[i] < x) i++;
while(a[j] > x) j--;
if(i <= j)
{
Swap(a[i],a[j]);
i++ ; j--;
}
} while(i <= j);
}
if(left
QuickSort(a, left, j);
if(i
QuickSort(a, i, right);
16
Quick Sort – Ví Dụ
CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT 1
Phân hoạch đọan [0,7]
i
0
1
2
left
1
2
3
4
5
6
2
8
5
5
1
6
4
X
17
j
7
1
5
right
Quick Sort – Ví Dụ
Phân hoạch đọan [0,7]
CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT 1
X
5
0
i
1
2
3
4
j
5
4
2
8
5
1
6
6
7
1
2
1
5
right
left
18
Quick Sort – Ví Dụ
CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT 1
Phân hoạch đọan [0,2]
0
1
j
2
4
2
1
3
i
4
5
6
7
5
8
6
1
2
1
5
right
left
19
CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT 1
Phân hoạch đọan [0,2]
i
0
4
1
j
2
3
4
5
6
7
2
1
5
8
6
1
2
1
5
X
left
right
20
Quick Sort – Ví Dụ
CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT 1
Phân hoạch đọan [4,7]
0
1
2
3
i
4
1
2
4
5
8
left
21
5
6
j
7
6
1
2
1
5
X
right
Quick Sort – Ví Dụ
CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT 1
Phân hoạch đọan [5,7]
0
1
2
3
j
4
1
2
4
5
6
left
22
i
5
8
6
7
1
2
1
5
right
Quick Sort – Ví Dụ
CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT 1
Phân hoạch đọan [5,7]
0
1
2
3
4
i
5
1
2
4
5
6
8
left
23
6
j
7
1
2
1
5
right
CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT 1
Quick Sort – Ví Dụ
0
1
2
3
4
5
6
7
1
2
4
5
6
8
1
2
1
5
24
CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT 1
Độ Phức Tạp Của Quick Sort
25