You are on page 1of 16

Chương 5 NỘI DUNG 5.1.

Bài toán sắp xếp


Sắp xếp (Sorting) 5.1. Bài toán sắp xếp • 5.1.1. Bài toán sắp xếp
5.2. Ba thuật toán sắp xếp cơ bản • 5.1.2. Giới thiệu sơ lược về các thuật toán sắp xếp

5.3. Sắp xếp trộn (Merge Sort)


5.4. Sắp xếp nhanh (Quick Sort)
5.5. Sắp xếp vun đống (Heap Sort)
5.6. Cận dưới cho độ phức tạp tính toán của bài toán sắp xếp
Heap Sort Quick Sort
5.7. Các phương pháp sắp xếp đặc biệt
William A. Martin, Sorting. ACM Computing Surveys, Vol. 3, Nr 4, Dec 1971, pp. 147-174.
" ...The bibliography appearing at the end of this article lists 37 sorting algorithms
and 100 books and papers on sorting published in the last 20 years...
Suggestions are made for choosing the algorithm best suited to a given situation."

D. Knuth: 40% thời gian hoạt động của các máy tính là dành cho sắp xếp!

NGUYỄN ĐỨC NGHĨA NGUYỄN ĐỨC NGHĨA 2 NGUYỄN ĐỨC NGHĨA 3


Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN

5.1.1. Bài toán sắp xếp 5.1.1. Bài toán sắp xếp 5.1.1. Bài toán sắp xếp

• Sắp xếp (Sorting) • Chú ý: Dạng tổng quát:


– Quá trình tổ chức lại dữ liệu theo thứ tự giảm dần hoặc tăng • Nếu sắp xếp trực tiếp trên bản ghi -> đòi hỏi di chuyển vị trí
dần (ascending/descending) Input: Dãy n số A = (a1, a2, …, an)
bản ghi -> tốn kém.
• Dữ liệu cần sắp xếp có thể là
– Số nguyên (Integers) • Xây dựng bảng khoá gồm các bản ghi chỉ có 2 trường: Output: Một hoán vị (sắp xếp lại) (a'1,…, a’n) của dãy số đã cho
– Xâu ký tự (Character strings) – "khoá" chứa giá trị khoá, thoả mãn
– Đối tượng (Objects) – "con trỏ" để ghi địa chỉ của bản ghi tương ứng. a’1 ≤ … ≤ a’n
• Khoá sắp xếp (Sort key) • Sắp xếp trên bảng khoá không làm thay đổi bảng chính
– Bộ phận của bản ghi xác định thứ tự sắp xếp của bản ghi
• Nhưng trình tự các bản ghi trong bảng khoá cho phép xác định
trong danh sách.
– Bản ghi sắp xếp theo thứ tự của các khoá. trình tự các bản ghi trong bảng chính.

NGUYỄN ĐỨC NGHĨA 4 NGUYỄN ĐỨC NGHĨA 5 NGUYỄN ĐỨC NGHĨA 6


Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN

5.1.1. Bài toán sắp xếp 5.1.1. Bài toán sắp xếp 5.1.1. Bài toán sắp xếp

• Các loại thuật toán sắp xếp • Các đặc trưng của một thuật toán sắp xếp:
• Ứng dụng của sắp xếp:
– Sắp xếp trong (internal sort) – Tại chỗ (in place): nếu không gian nhớ phụ mà thuật toán đòi hỏi là
– Quản trị cơ sở dữ liệu (Database management); O(1), nghĩa là bị chặn bởi hằng số không phụ thuộc vào độ dài của dãy
– Khoa học và kỹ thuật (Science and engineering); • Đòi hỏi họ dữ liệu được đưa toàn bộ vào bộ nhớ trong cần sắp xếp.
của máy tính
– Các thuật toán lập lịch (Scheduling algorithms),
• ví dụ thiết kế chương trình dịch, truyền thông,... (compiler – Sắp xếp ngoài (external sort) – Ổn định (stable): Nếu các phần tử có cùng giá trị vẫn giữ nguyên thứ tự
tương đối của chúng như trước khi sắp xếp.
design, telecommunication); • Họ dữ liệu không thể cùng lúc đưa toàn bộ vào bộ nhớ
– Máy tìm kiếm web (Web search engine); trong, nhưng có thể đọc vào từng bộ phận từ bộ nhớ
– và nhiều ứng dụng khác… ngoài

Create PDF files without this message by purchasing 7novaPDF printer (http://www.novapdf.com)
NGUYỄN ĐỨC NGHĨA
Bộ môn KHMT - ĐHBKHN
NGUYỄN ĐỨC NGHĨA
Bộ môn KHMT - ĐHBKHN
8 NGUYỄN ĐỨC NGHĨA
Bộ môn KHMT - ĐHBKHN
9
5.1.1. Bài toán sắp xếp 5.1.2. Giới thiệu sơ lược về các thuật toán sắp xếp Các thuật toán sắp xếp dựa trên phép so sánh

• 2 phép toán cơ bản thường phải sử dụng: Name Average Worst Memory Stable Method

– Đổi chỗ (Swap): Thời gian thực hiện là O(1)
Bubble sort O(n²) O(1) Yes Exchanging
Cocktail sort — O(n²) O(1) Yes Exchanging
Simple Fancier Comparison Specialized Handling Comb sort O(n log n) O(n log n) O(1) No Exchanging
void swap( datatype &a, datatype &b){ algorithms: algorithms: lower bound: algorithms: huge data Gnome sort — O(n²) O(1) Yes Exchanging
datatype temp = a; //datatype-kiểu dữ liệu của phần tử O(n2) O(n log n) (n log n) O(n) sets Selection sort O(n²) O(n²) O(1) No Selection

a = b; Insertion sort O(n + d) O(n²) O(1) Yes Insertion


Shell sort — O(n log² n) O(1) No Insertion
b = temp; Binary tree sort O(n log n) O(n log n) O(n) Yes Insertion
} Insertion sort Heap sort Bucket sort External Library sort O(n log n) O(n²) O(n) Yes Insertion
– So sánh: Compare(a, b) trả lại Selection sort Merge sort Radix sort sorting Merge sort O(n log n) O(n log n) O(n) Yes Merging
Bubble sort Quick sort
• true nếu a đi trước b trong thứ tự cần sắp xếp Shell sort …
In-place merge sort O(n log n) O(n log n) O(1) Yes Merging

• false nếu trái lại. … Heapsort O(n log n) O(n log n) O(1) No Selection
Smoothsort — O(n log n) O(1) No Selection
Quicksort O(n log n) O(n²) O(log n) No Partitioning
Introsort O(n log n) O(n log n) O(log n) No Hybrid
Patience sorting — O(n²) O(n) No Insertion

NGUYỄN ĐỨC NGHĨA 10 NGUYỄN ĐỨC NGHĨA 11 NGUYỄN ĐỨC NGHĨA 12


Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN

Các thuật toán sắp xếp không dựa trên phép so sánh NỘI DUNG 5.2. Ba thuật toán sắp xếp cơ bản

Name Average Worst Memory Stable n << 2k? 5.1. Bài toán sắp xếp • 5.2.1. Sắp xếp chèn (Insertion Sort)
Pigeonhole sort O(n+2k) O(n+2k) O(2k) Yes Yes
5.2. Ba thuật toán sắp xếp cơ bản • 5.2.2. Sắp xếp lựa chọn (Selection Sort)
Bucket sort O(n·k) O(n²·k) O(n·k) Yes No • 5.2.3. Sắp xếp nổi bọt (Bubble Sort)
Counting sort O(n+2k) O(n+2k) O(n+2k) Yes Yes
5.3. Sắp xếp trộn (Merge Sort)
LSD Radix sort O(n·k/s) O(n·k/s) O(n) Yes No 5.4. Sắp xếp nhanh (Quick Sort)
MSD Radix sort O(n·k/s) O(n·(k/s)·2s) O((k/s)·2s) No No 5.5. Sắp xếp vun đống (Heap Sort)
5.6. Cận dưới cho độ phức tạp tính toán của bài toán sắp xếp
Spreadsort O(n·k/log(n)) O(n·(k-log(n))0.5) O(n) No No
5.7. Các phương pháp sắp xếp đặc biệt
Các thông số trong bảng
n - số phần tử cần sắp xếp
k - kích thước mỗi phần tử
s - kích thước bộ phận được sử dụng khi cài đặt.
Nhiều thuật toán được xây dựng dựa trên giả thiết là n << 2k.
NGUYỄN ĐỨC NGHĨA 13 NGUYỄN ĐỨC NGHĨA 14 NGUYỄN ĐỨC NGHĨA 15
Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN

5.2.1. Sắp xếp chèn (Insertion Sort) Sắp xếp chèn (Insertion Sort) Sắp xếp chèn (Insertion Sort)

Phỏng theo cách làm của người Phỏng theo cách làm của người Phỏng theo cách làm của người
chơi bài khi cần "chèn" thêm một chơi bài khi cần "chèn" thêm một chơi bài khi cần "chèn" thêm một
con bài vào bộ bài đã được sắp con bài vào bộ bài đã được sắp con bài vào bộ bài đã được sắp
xếp trên tay. xếp trên tay. xếp trên tay.

Để chèn 12, ta cần tạo chỗ cho Để chèn 12, ta cần tạo chỗ cho Để chèn 12, ta cần tạo chỗ cho
nó bởi việc dịch chuyển đầu tiên nó bởi việc dịch chuyển đầu tiên nó bởi việc dịch chuyển đầu tiên
là 36 và sau đó là 24. là 36 và sau đó là 24. là 36 và sau đó là 24.

NGUYỄN ĐỨC NGHĨA NGUYỄN ĐỨC NGHĨA NGUYỄN ĐỨC NGHĨA


Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com)
Bộ môn KHMT - ĐHBKHN
16
Bộ môn KHMT - ĐHBKHN
17
Bộ môn KHMT - ĐHBKHN
18
Sắp xếp chèn (Insertion Sort) Don’t start coding 5.2.1. Sắp xếp chèn (Insertion Sort)

• Thuật toán:
You must design a working algorithm first. – Tại bước k = 1, 2, ..., n, đưa phần tử thứ k trong mảng đã cho vào đúng
Phỏng theo cách làm của người vị trí trong dãy gồm k phần tử đầu tiên.
chơi bài khi cần "chèn" thêm một – Kết quả là sau bước k, k phần tử đầu tiên là được sắp thứ tự.
con bài vào bộ bài đã được sắp void insertionSort(int a[], int array_size) {
xếp trên tay. int i, j, last;
Giải thích:
for (i=1; i < array_size; i++) {
Để chèn 12, ta cần tạo chỗ cho • Ở đầu lần lặp i của vòng
last = a[i];
nó bởi việc dịch chuyển đầu tiên "for" ngoài, dữ liệu từ a[0]
j = i;
là 36 và sau đó là 24. đến a[i-1] là được sắp xếp.
while ((j > 0) && (a[j-1] > last)) { • Vòng lặp "while" tìm vị trí
a[j] = a[j-1]; cho phần tử tiếp theo (last
j = j - 1; }// end while =a[i]) trong dãy gồm i phần
a[j] = last; tử đầu tiên.
} // end for
} // end of isort
NGUYỄN ĐỨC NGHĨA 19 20 NGUYỄN ĐỨC NGHĨA 21
Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN

Ví dụ Insertion sort (1) Ví dụ Insertion sort (1) Ví dụ: Insertion Sort (2)

1 2 3 8 7 9 10 12 23 18 15 16 17 14 1 2 3 7 8 9 10 12 15 16 18 17 23 14

1 2 3 7 8 9 10 12 23 18 15 16 17 14 1 2 3 7 8 9 10 12 15 16 17 18 23 14

1 2 3 7 8 9 10 12 18 23 15 16 17 14 1 2 3 7 8 9 10 12 15 16 17 18 14 23

1 2 3 7 8 9 10 12 18 15 23 16 17 14 1 2 3 7 8 9 10 12 15 16 17 14 18 23

1 2 3 7 8 9 10 12 15 18 23 16 17 14 1 2 3 7 8 9 10 12 15 16 14 17 18 23

1 2 3 7 8 9 10 12 15 18 16 23 17 14 1 2 3 7 8 9 10 12 15 14 16 17 18 23

1 2 3 7 8 9 10 12 14 15 16 17 18 23
1 2 3 7 8 9 10 12 15 16 18 23 17 14

13 phép đổi chỗ:


20 phép so sánh:

NGUYỄN ĐỨC NGHĨA 22 NGUYỄN ĐỨC NGHĨA 23 NGUYỄN ĐỨC NGHĨA 24


Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN

Các đặc tính của Insertion Sort Thử nghiệm insertion sort 5.2.2. Sắp xếp chọn (Selection Sort)

• Sắp xếp chèn là tại chỗ và ổn định (In place and Stable)
#include <stdlib.h> • Thuật toán void swap(int &a,int &b)
#include <stdio.h>
– Tìm phần tử nhỏ nhất đưa vào vị trí 1 {
void insertionSort(int a[], int array_size);
• Phân tích thời gian tính của thuật toán int a[1000]; – Tìm phần tử nhỏ tiếp theo đưa vào vị trí 2
int temp = a;
a = b;
– Best Case: 0 hoán đổi, n-1 so sánh (khi dãy đầu vào là đã được sắp) int main() {
– Tìm phần tử nhỏ tiếp theo đưa vào vị trí 3
b = temp;
int i, N; }
– Worst Case: n2/2 hoán đổi và so sánh (khi dãy đầu vào có thứ tự printf("\nGive n = "); scanf("%i", &N); – …
ngược lại với thứ tự cần sắp xếp) //seed random number generator void selectionSort(int a[], int n){
– Average Case: n2/4 hoán đổi và so sánh srand(getpid());
int i, j, min, temp;
//fill array with random integers
• Thuật toán này có thời gian tính trong tình huống tốt nhất là for (i = 0; i < N; i++) for (i = 0; i < n-1; i++) {
tốt nhất a[i] = rand(); min = i;
//perform insertion sort on array
for (j = i+1; j < n; j++){
• Là thuật toán sắp xếp tốt đối với dãy đã gần được sắp xếp insertionSort(a, N);
if (a[j] < a[min]) min = j;
printf("\nOrdered sequence:\n");
– Nghĩa là mỗi phần tử đã đứng ở vị trí rất gần vị trí trong thứ tự cần for (i = 0; i < N; i++) }
sắp xếp printf("%8i", a[i]); swap(a[i], a[min]);
getch();
}
}
}
NGUYỄN ĐỨC NGHĨA NGUYỄN ĐỨC NGHĨA NGUYỄN ĐỨC NGHĨA
Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com)
25
Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN
26
Bộ môn KHMT - ĐHBKHN
27
Selection Sort Ví dụ: Selection Sort 5.2.3. Sắp xếp nổi bọt - Bubble Sort
Nhận xét: • Đơn giản, thường được sử dụng như ví dụ minh hoạ cho các giáo
trình nhập môn lập trình.
• Best case: 0 đổi chỗ (n-1 như trong đoạn mã), n2/2 so sánh.
• Worst case: n - 1 đổi chỗ và n2/2 so sánh. • Kém hiệu quả hơn các thuật toán khác -> ngoài mục đích giảng dạy,
Sắp xếp nổi bọt rất ít khi được sử dụng.
• Average case: O(n) đổi chỗ và n2/2 so sánh.
• Ưu điểm nổi bật của sắp xếp chọn là số phép đổi chỗ là ít.
Điều này là có ý nghĩa nếu như việc đổi chỗ là tốn kém.

NGUYỄN ĐỨC NGHĨA 28 NGUYỄN ĐỨC NGHĨA 29 NGUYỄN ĐỨC NGHĨA 30


Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN

5.2.3. Sắp xếp nổi bọt - Bubble Sort 5.2.3. Sắp xếp nổi bọt - Bubble Sort Ví dụ: Bubble Sort
• Bắt đầu từ đầu dãy, thuật toán tiến hành so sánh mỗi phần tử với void swap(int &a,int &b)
void bubbleSort(int a[], int n){ {
phần tử đi sau nó và thực hiện đổi chỗ, nếu chúng không theo đúng 7 4 1 9 2 4 1 7 2 9 1 4 2 7 9
int i, j; int temp = a;
thứ tự. a = b;
for (i = (n-1); i >= 0; i--) { b = temp; 4 7 1 9 2 1 4 7 2 9 1 4 2 7 9
• Quá trình này sẽ được lặp lại cho đến khi gặp lần duyệt từ đầu dãy for (j = 1; j <= i; j++){ }
đến cuối dãy mà không phải thực hiện đổi chỗ (tức là tất cả các phần if (a[j-1] > a[j]) 4 1 7 9 2 1 4 7 2 9 1 2 4 7 9
tử đã đứng đúng vị trí). swap(a[j-1],a[j]); 4 1 7 9 2 1 4 2 7 9
• Cách làm này đã đẩy phần tử lớn nhất xuống cuối dãy, trong khi đó }
những phần tử có giá trị nhỏ hơn được dịch chuyển về đầu dãy. } 4 1 7 2 9
}
• Best case: 0 đổi chỗ, n2/2 so sánh. i= 4 i= 3 i= 2
• Worst case: n2/2 đổi chỗ và so sánh.
Chú ý:
• Average case: n2/4 đổi chỗ và n2/2 so sánh. – Các phần tử được đánh chỉ số bắt đầu từ 0.
– n=5

NGUYỄN ĐỨC NGHĨA 31 NGUYỄN ĐỨC NGHĨA 32 NGUYỄN ĐỨC NGHĨA 33


Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN

So sánh ba thuật toán cơ bản Tổng kết 3 thuật toán sắp xếp cơ bản NỘI DUNG

5.1. Bài toán sắp xếp


Insertion Bubble Selection
5.2. Ba thuật toán sắp xếp cơ bản
Comparisons:
5.3. Sắp xếp trộn (Merge Sort)
Best Case (n) (n2) (n2)
Average Case (n2) (n2) (n2) 5.4. Sắp xếp nhanh (Quick Sort)
Worst Case (n2) (n2) (n2) 5.5. Sắp xếp vun đống (Heap Sort)
5.6. Cận dưới cho độ phức tạp tính toán của bài toán sắp xếp
Swaps
Best Case 0 0 (n) 5.7. Các phương pháp sắp xếp đặc biệt
Average Case (n2) (n2) (n)
Worst Case (n2) (n2) (n)

NGUYỄN ĐỨC NGHĨA NGUYỄN ĐỨC NGHĨA NGUYỄN ĐỨC NGHĨA


Create PDF files without this message by purchasing34novaPDF printer (http://www.novapdf.com)
Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN
35
Bộ môn KHMT - ĐHBKHN
36
Sắp xếp trộn (Merge Sort) Sắp xếp trộn (Merge Sort) Merge Sort

• Bài toán: Cần sắp xếp mảng A[1 .. n]: p q r


MERGE-SORT(A, p, r)
1 2 3 4 5 6 7 8

• Chia (Divide) 5 2 4 7 1 3 2 6
– Chia dãy gồm n phần tử cần sắp xếp ra thành 2 dãy, mỗi dãy có n/2 if p < r Kiểm tra điều kiện neo
phần tử
then q ← (p + r)/2
• Trị (Conquer) Chia (Divide)

– Sắp xếp mỗi dãy con một cách đệ qui sử dụng sắp xếp trộn MERGE-SORT(A, p, q) Trị (Conquer)
– Khi dãy chỉ còn một phần tử thì trả lại phần tử này MERGE-SORT(A, q + 1, r) Trị (Conquer)
Hoà nhập hai dòng xe theo Khoá
[độ liều lĩnh của lái xe]. • Tổ hợp (Combine) MERGE(A, p, q, r) Tổ hợp (Combine)
Lái xe liều lĩnh hơn sẽ vào trước! – Trộn (Merge) hai dãy con được sắp xếp để thu được dãy được sắp xếp
endif
gồm tất cả các phần tử của cả hai dãy con
• Lệnh gọi thực hiện thuật toán: MERGE-SORT(A, 1, n)

NGUYỄN ĐỨC NGHĨA 37 NGUYỄN ĐỨC NGHĨA 38 NGUYỄN ĐỨC NGHĨA 39


Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN

Trộn (Merge) - Pseudocode Thời gian tính của trộn Thời gian tính của sắp xếp trộn
MERGE-SORT Running Time

MERGE(A, p, q, r) • Khởi tạo (tạo hai mảng con tạm thời L và R): • Chia:
1. Tính n1 và n2 p q r
1 2 3 4 5 6 7 8 – (n1 + n2) = (n) – tính q như là giá trị trung bình của p và r: D(n) = (1)
2. Sao n1 phần tử đầu tiên vào L[1 . . n1] và n2
phần tử tiếp theo vào R[1 . . n2]
2 4 5 7 1 2 3 6
• Đưa các phần tử vào mảng kết quả (vòng lặp for cuối cùng): • Trị:
3. L[n1 + 1] ← ; R[n2 + 1] ← 
n1 n2 – n lần lặp, mỗi lần đòi hởi thời gian hằng số  (n) – giải đệ qui 2 bài toán con, mỗi bài toán kích thước n/2  2T (n/2)
4. i ← 1; j ← 1 • Tổ hợp:
• Tổng cộng thời gian của trộn là:
5. for k ← p to r do p q
– TRỘN (MERGE) trên các mảng con cỡ n phần tử đòi hỏi thời gian (n)
if L[ i ] ≤ R[ j ] – (n)
6.
L 2 4 5 7   C(n) = (n)
7. then A[k] ← L[ i ]
8. i ←i + 1
q+1 r
(1) nếu n =1
1 2 3 6 
9. else A[k] ← R[ j ]
R
T(n) = 2T(n/2) + (n) nếu n > 1
10. j←j+1 – Suy ra theo định lý thợ: T(n) = (n log n)
NGUYỄN ĐỨC NGHĨA 40 NGUYỄN ĐỨC NGHĨA 41 NGUYỄN ĐỨC NGHĨA 42
Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN

Ví dụ: Sắp xếp trộn Cài đặt merge: Trộn A[first..mid] và A[mid+1.. last] Cài đặt mergesort
1 2 3 4 5 6 7 8
void merge(DataType A[], int first, int mid, int last){ void mergesort(DataType A[], int first, int last)
8 2 9 4 5 3 1 6 DataType tempA[MAX_SIZE]; // mảng phụ
{
1 2 3 4 5 6 7 8
int first1 = first; int last1 = mid;
if (first < last)
Divide 8 2 9 4 5 3 1 6 int first2 = mid + 1; int last2 = last; int index = first1;
{ // chia thành hai dãy con
for (; (first1 <= last1) && (first2 <= last2); ++index){
int mid = (first + last)/2; // chỉ số điểm giữa
1 2 3 4 5 6 7 8
if (A[first1] < A[first2]) {
Divide 8 2 9 4 5 3 1 6 tempA[index] = A[first1]; ++first1;} // sắp xếp dãy con trái A[first..mid]
1 2 3 4 5 6 7 8
else mergesort(A, first, mid);
1 phần tử 8 2 9 4 5 3 1 6 { tempA[index] = A[first2]; ++first2;} } // sắp xếp dãy con phải A[mid+1..last]
1 2 3 4 5 6 7 8
for (; first1 <= last1; ++first1, ++index) mergesort(A, mid+1, last);
tempA[index] = A[first1]; // sao nốt dãy con 1
Merge 2 8 4 9 3 5 1 6 // Trộn hai dãy con
for (; first2 <= last2; ++first2, ++index)
merge(A, first, mid, last);
1 2 3 4 5 6 7 8
tempA[index] = A[first2]; // sao nốt dãy con 2
Merge 2 4 8 9 1 3 5 6 for (index = first; index <= last; ++index)
} // end if
A[index] = tempA[index]; // sao trả mảng kết quả } // end mergesort
1 2 3 4 5 6 7 8
} // end merge
Kết quả: 1 2 3 4 5 6 8 9
Chú ý: DataType: kiểu dữ liệu phần tử mảng. Lệnh gọi thực hiện mergesort(A,0,n-1)
NGUYỄN ĐỨC NGHĨA NGUYỄN ĐỨC NGHĨA NGUYỄN ĐỨC NGHĨA
Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com)
Bộ môn KHMT - ĐHBKHN
43
Bộ môn KHMT - ĐHBKHN
44
Bộ môn KHMT - ĐHBKHN
45
NỘI DUNG 5.4. Sắp xếp nhanh (Quick Sort) 5.4.1. Sơ đồ Quick Sort

5.1. Bài toán sắp xếp • 5.4.1. Sơ đồ tổng quát • Thuật toán sắp xếp nhanh được phát triển bởi
• 5.4.2. Phép phân đoạn Hoare năm 1960 khi ông đang làm việc cho
5.2. Ba thuật toán sắp xếp cơ bản hãng máy tính nhỏ Elliott Brothers ở Anh.
• 5.4.3. Độ phức tạp của sắp xếp nhanh
5.3. Sắp xếp trộn (Merge Sort) • Theo thống kê tính toán, Quick sort (sẽ viết tắt là
QS) là thuật toán sắp xếp nhanh nhất hiện nay.
5.4. Sắp xếp nhanh (Quick Sort)
• QS có thời gian tính trung bình là O(n log n), tuy C.A.R. Hoare
5.5. Sắp xếp vun đống (Heap Sort) nhiên thời gian tính tồi nhất của nó lại là O(n2). January 11, 1934
ACM Turing Award, 1980
5.6. Cận dưới cho độ phức tạp tính toán của bài toán sắp xếp • QS là thuật toán sắp xếp tại chỗ, nhưng nó Photo: 2006

không có tính ổn định.


5.7. Các phương pháp sắp xếp đặc biệt
• QS khá đơn giản về lý thuyết, nhưng lại không
dễ cài đặt .

đường nằm ngang cho biết pivot

NGUYỄN ĐỨC NGHĨA 46 NGUYỄN ĐỨC NGHĨA 47 NGUYỄN ĐỨC NGHĨA 48


Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN

10 Algorithms in 20th Century 5.4.1. Sơ đồ Quick Sort 5.4.1. Sơ đồ Quick Sort

có ảnh hưởng sâu rộng đến việc phát triển và ứng dụng của khoa • Dựa trên kỹ thuật chia để trị. 1. Neo đệ qui (Base case). Nếu dãy chỉ còn không quá 1 phần tử thì nó là
học kỹ thuật …
• Có thể được mô tả đệ qui tương tự như Merge Sort dãy được sắp và trả lại ngay dãy này mà không phải làm gì cả.
1946: The Metropolis Algorithm for Monte Carlo • Ngược lại với Merge Sort, trong QS 2. Chia (Divide):
1947: Simplex Method for Linear Programming // Tính toán khoa học
– thao tác chia là phức tạp, • Chọn 1 phần tử trong dãy và gọi nó là phần tử chốt p (pivot).
1950: Krylov Subspace Iteration Method
1951: The Decompositional Approach to Matrix Computations – nhưng thao tác tổng hợp lại đơn giản. • Chia dãy đã cho ra thành 2 dãy con:
1957: The Fortran Optimizing Compiler – Dãy con trái (L) gồm những phần tử không lớn hơn phần tử
• Điểm mấu chốt để thực hiện QS chính là thao tác chia.
1959: QR Algorithm for Computing Eigenvalues chốt,
1962: Quicksort Algorithms for Sorting • => Phụ thuộc vào thuật toán thực hiện thao tác này mà ta có các – Dãy con phải (R) gồm các phần tử không nhỏ hơn phần tử
1965: Fast Fourier Transform // Xử lý ảnh dạng QS cụ thể. chốt. Thao tác này được gọi là "Phân đoạn" (Partition).
1977: Integer Relation Detection
1987: Fast Multipole Method 3. Trị (Conquer): Lặp lại một cách đệ qui thuật toán đối với 2 dãy con L
và R.
Computing in Science & Engineering, January/February 2000
4. Tổng hợp (Combine): Dãy được sắp xếp là L p R.
Science, Vol. 287, No. 5454, p. 799, February 2000

NGUYỄN ĐỨC NGHĨA 50 NGUYỄN ĐỨC NGHĨA-Bộ môn KHMT -ĐHBKHN


Bộ môn KHMT - ĐHBKHN 51

Các bước của QuickSort Sơ đồ tổng quát của QS Sơ đồ tổng quát của QS
• Sơ đồ tổng quát của QS có thể mô tả như sau: • Khi dãy con chỉ còn một số lượng không lớn phần tử (VD: 9 phần
A 81 43 31 57 Chọn pivot
Quick-Sort(A, Left, Right) tử) -> sử dụng các thuật toán đơn giản để sắp xếp dãy này, chứ
13 75
92
26
0 không nên tiếp tục chia nhỏ.
65 1. if (Left < Right ) {
• Thuật toán trong tình huống như vậy có thể mô tả như sau:
2. Pivot = Partition(A, Left, Right);
L R Phân đoạn A
0
13 43 31
65
75
81
3. Quick-Sort(A, Left, Pivot –1);
26 57
92 Quick-Sort(A, Left, Right)
4. Quick-Sort(A, Pivot +1, Right); }
1. if (Right - Left < n0 )
QuickSort(L) và
L R QuickSort(R) 2. Insertion_sort(A, Left, Right);
0 13 26 31 43 57 65 75 81 92 • Hàm Partition(A, Left, Right) thực hiện chia A[Left..Right] thành 2
đoạn A[Left..Pivot –1 ] và A[Pivot+1..Right] sao cho: 3. else {
• Các phần tử trong A[Left..Pivot –1] ≤ A[Pivot] 4. Pivot = Partition(A, Left, Right);
A 0 13 26 31 43 57 65 75 81 92 OK! A được sắp • Các phần tử trong A[Pivot+1..Right] ≥ A[Pivot]. 5. Quick-Sort(A, Left, Pivot –1);
• Lệnh gọi thực hiện thuật toán Quick-Sort(A, 1, n) 6. Quick-Sort(A, Pivot +1, Right); }
NGUYỄN ĐỨC NGHĨA NGUYỄN ĐỨC NGHĨA NGUYỄN ĐỨC NGHĨA
Create PDF files without this message by purchasing52novaPDF printer (http://www.novapdf.com)
Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN
53
Bộ môn KHMT - ĐHBKHN
54
5.4.2. Thao tác chia Chọn phần tử chốt Chọn phần tử chốt
• Trong QS thao tác chia bao gồm 2 công việc:
– Chọn phần tử chốt p. • Việc chọn phần tử chốt có vai trò quyết định đối với hiệu quả
của thuật toán. • Người ta thường sử dụng các cách chọn phần tử chốt sau đây:
– Phân đoạn: Chia dãy đã cho ra thành 2 dãy con
• Thao tác phân đoạn có thể cài đặt (tại chỗ) với thời gian (n). • Tốt nhất nếu chọn được phần tử chốt là phần tử đứng giữa – Chọn phần tử trái nhất (đứng đầu) làm phần tử chốt.
• Hiệu quả của thuật toán phụ thuộc rất nhiều vào việc phần tử nào trong danh sách được sắp xếp (ta gọi phần tử như vậy là trung – Chọn phần tử phải nhất (đứng cuối) làm phần tử chốt.
được chọn làm phần tử chốt: vị/median). – Chọn phần tử đứng giữa danh sách làm phần tử chốt.
– Thời gian tính trong tình huống tồi nhất của QS là O(n2). • Khi đó, sau log2n lần phân đoạn ta sẽ đạt tới danh sách với – Chọn phần tử trung vị trong 3 phần tử đứng đầu, đứng giữa
• Xảy ra khi danh sách là đã được sắp xếp và phần tử chốt kích thước bằng 1. và đứng cuối làm phần tử chốt ().
được chọn là phần tử trái nhất của dãy. • Tuy nhiên, điều đó rất khó thực hiện. – Chọn ngẫu nhiên một phần tử làm phần tử chốt.
– Nếu phần tử chốt được chọn ngẫu nhiên -> QS có độ phức tạp
tính toán là O(n log n).

NGUYỄN ĐỨC NGHĨA 55 NGUYỄN ĐỨC NGHĨA 56 NGUYỄN ĐỨC NGHĨA 57


Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN

Thuật toán phân đoạn Phần tử chốt là phần tử đứng đầu Ví dụ

• Ta xây dựng hàm Partition(a, left, right) làm việc sau: Partition(a, left, right)
pivot được chọn là Vị trí: 0 1 2 3 4 5 6 7 8 9
i = left; j = right + 1; pivot = a[left];
• Input: Mảng a[left .. right]. while i < j do
phần tử đứng đầu
Khoá (Key): 9 1 11 17 13 18 4 12 14 5
• Output: Phân bố lại các phần tử của mảng đầu vào và trả lại i = i + 1; > > <
chỉ số jpivot thoả mãn: while i  right and a[i] < pivot do i = i + 1; lần 1while: 9 1 5 17 13 18 4 12 14 11
j = j – 1;
– a[jpivot] chứa giá trị ban đầu của a[left], > < < <
while j  left and a[j] > pivot do j = j – 1; lần 2while: 9 1 5 4 13 18 17 12 14 11
– a[i] ≤ a[jpivot], với mọi left ≤ i < pivot, swap(a[i] , a[j]); < >< <
j là chỉ số (jpivot) cần trả lại,
– a[j] ≥ a[jpivot]), với mọi pivot < j ≤ right. swap(a[i], a[j]); swap(a[j], a[left]); do đó cần đổi chỗ a[left] và a[j]
lần 3while: 9 1 5 13 4 18 17 12 14 11
return j;
2 lần đổi chỗ: 4 1 5 9 13 18 17 12 14 11

i Sau khi chọn pivot, dịch các con trỏ i và j từ đầu và cuối mảng j
và đổi chỗ cặp phần tử thoả mãn a[i] > pivot và a[j] < pivot

NGUYỄN ĐỨC NGHĨA 58 NGUYỄN ĐỨC NGHĨA 59


Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN

Ví dụ: Phân đoạn với pivot là phần tử đứng đầu Phần tử chốt là phần tử đứng giữa Phần tử chốt là phần tử đứng cuối
PartitionMid(a, left, right);
Chọn pivot: 7 2 8 3 5 9 6
pivot được chọn là
int PartitionR(int a[], int p, int r) { void quickSort(int a[], int p, int r) {
i = left; j = right; pivot = a[(left + right)/2]; int x = a[r]; if (p < r) {
phần tử đứng giữa
Phân đoạn: Con trỏ 7 2 8 3 5 9 6 repeat int j = p - 1; int q = PartitionR(a, p, r);
< > while a[i] < pivot do i = i + 1; for (int i = p; i < r; i++) { quickSort(a, p, q - 1);
2 nhỏ hơn pivot 7 2 8 3 5 9 6 while pivot < a[j] do j = j - 1; if (x >= a[i]) quickSort(a, q + 1, r);
< > if i <= j { j = j + 1; swap(a[i], a[j]); } }
đổi chỗ 6, 8 7 2 6 3 5 9 8 swap(a[i], a[j]); } }
< > i = i + 1; j = j - 1; a[r] = a[j + 1]; a[j + 1] = x;
3,5 nhỏ hơn 9 lớn hơn 7 2 6 3 5 9 8 until i > j; return (j + 1);
return j; }
Kết thúc phân đoạn 7 2 6 3 5 9 8
• Cài đặt thuật toán phân đoạn trong đó pivot được chọn là phần tử đứng
Đưa pivot vào vị trí 5 2 6 3 7 9 8 giữa (Đây cũng là cách cài đặt mà TURBO C lựa chọn).

NGUYỄN ĐỨC NGHĨA NGUYỄN ĐỨC NGHĨA


Create PDF files without this61message by purchasing novaPDF printer (http://www.novapdf.com) Bộ môn KHMT - ĐHBKHN
62
Bộ môn KHMT - ĐHBKHN
63
void swap(int &a,int &b)
Cài đặt QUICK SORT { int t = a; a = b; b = t; } Cài đặt Quick Sort (dễ đọc hơn?) Chương trình DEMO
int Partition(int a[], int left, int right) { /* CHUONG TRINH DEMO QUICK SORT */
int i, j, pivot; int Partition(int a[], int L, int R) void quick_sort(int a[], int left, int right) /* include: stdlib.h; stdio.h; conio.h; process.h; include time.h */
void quick_sort(int a[], int left, int right);
i = left; j = right + 1; pivot = a[left]; { {
void swap(int &a, int &b);
while (i < j) { int i, j, p; int p;
int Partition(int a[], int left, int right);
i = i + 1; while ((i <= right)&&(a[i] < pivot)) i++; i = L; j = R + 1; p = a[L]; if (left < right) int a[1000]; int n; // n - so luong phan tu cua day can sap xep
j--; while ((j >= left)&& (a[j] > pivot)) j--; while (i < j) { { void main() {
swap(a[i] , a[j]); } i = i + 1; pivot = Partition(a, left, right); int i; clrscr();
swap(a[i], a[j]); swap(a[j], a[left]); printf("\n Give n = "); scanf("%i",&n); randomize();
while ((i <= R)&&(a[i]<p)) i++; if (left < pivot)
return j; for (i = 0; i < n; i++) a[i] = rand(); // Tao day ngau nhien
j--; quick_sort(a, left, pivot-1); printf("\nDay ban dau la: \n");
}
while ((j >= L)&& (a[j]>p)) j--; if (right > pivot) for (i = 0; i < n; i++) printf("%8i ", a[i]);
void quick_sort(int a[], int left, int right) {
quick_sort(a, 0, n-1); // Thuc hien quick sort
int pivot; swap(a[i] , a[j]); quick_sort(a, pivot+1, right);}
printf("\n Day da duoc sap xep.\n");
if (left < right) { } } for (i = 0; i < n; i++) printf("%8i ", a[i]);
pivot = Partition(a, left, right); swap(a[i], a[j]); swap(a[j], a[L]); a[n]=32767;
if (left < pivot) quick_sort(a, left, pivot-1); return j; for (i = 0; i < n; i++)
if (right > pivot) quick_sort(a, pivot+1, right);} if (a[i]>a[i+1]) {printf(" ??????? Loi o vi tri: %6i ", i); getch(); }
}
printf("\n Correct!"); getch();
}
}

NGUYỄN ĐỨC NGHĨA 64 NGUYỄN ĐỨC NGHĨA 65 NGUYỄN ĐỨC NGHĨA 66


Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN

Phân đoạn không cân bằng


Thời gian tính của Quick-Sort
30 19 24 28 41 34 15 43 20 12 36
(Unbalanced partition)
T(q) O(n) T(n-q)
19 24 28 15 20 12 30 41 34 43 36 • Thời gian tính của Quick-Sort phụ thuộc vào việc phép phân chia là Công thức đệ qui là:
cân bằng (balanced) hay không cân bằng (unbalanced), và điều
15 12 19 24 28 20 34 36 41 43 đó lại phụ thuộc vào việc phần tử nào được chọn làm chốt. T(n) = T(n – 1) + T(0) + Θ(n)
1. Phân đoạn không cân bằng: thực sự không có phần nào cả, do T (0) = T (1) = 1
12 15 20 24 28 34 36 đó một bài toán con có kích thước n – 1 còn bài toán kia có kích T ( n ) = T ( n − 1) + n
thước 0.
T ( n − 1) = T ( n − 2) + ( n − 1) n
2. Phân đoạn hoàn hảo (Perfect partition): việc phân đoạn luôn
12 15 20 24 28 34 36 T ( n − 2) = T ( n − 3) + ( n − 2)
được thực hiện dưới dạng phân đôi, như vậy mỗi bài toán con 1
... n–1
có kích thước cỡ n/2.
12 15 19 20 24 28 34 36 41 43 T ( 2 ) = T (1) + ( 2)
3. Phân đoạn cân bằng: việc phân đoạn được thực hiện ở đâu đó 1 n–2
O(1)
quanh điểm giữa, nghĩa là một bài toán con có kích thước n – k T ( n ) = T (1) + i = 2 i
n

còn bài toán kia có kích thước k. 1


12 15 19 20 24 28 30 34 36 41 43 = O (n2 ) 2

T (0) = T (1) = 1 Ta sẽ xét từng tình huống! 1 1


T (n ) = T (q ) +
NGUYỄN − qNGHĨA
T (nĐỨC ) + O (n) + O (1) 67 NGUYỄN ĐỨC NGHĨA 68 NGUYỄN ĐỨC NGHĨA 69
Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN

Khi phần tử chốt được chọn là phần tử đứng đầu: Phân đoạn hoàn hảo - Perfect partition Thời gian tính trung bình của QS
Tình huống tồi nhất xảy ra khi dãy đầu vào là đã được sắp xếp QuickSort Average Case

1 2 3 4 5 6 7 8 9 10 11 Công thức đệ qui: • Giả sử rằng pivot được chọn ngẫu nhiên trong số các
phần tử của dãy đầu vào
1 2 3 4 5 6 7 8 9 10 11 T(n) = T(n/2) + T(n/2) + Θ(n) • Tất cả các tình huống sau đây là đồng khả năng:
– Pivot là phần tử nhỏ nhất trong dãy
T (n ) = 2T (n / 2) + (n ) – Pivot là phần tử nhỏ nhì trong dãy
2 3 4 5 6 7 8 9 10 11
– Pivot là phần tử nhỏ thứ ba trong dãy
T ( n ) =  ( n log n ) It's Best Case!

3 4 5 6 7 8 9 10 11 – Pivot là phần tử lớn nhất trong dãy
Theo định lý thợ ! • Điều đó cũng là đúng khi pivot luôn được chọn là phần
T (0) = T (1) = 1 4 5 6 7 8 9 10 11 tử đầu tiên, với giả thiết là dãy đầu vào là hoàn toàn
ngẫu nhiên
T ( n ) = T (n − 1) + n
NGUYỄN ĐỨC NGHĨA 71
Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com)
70
Bộ môn KHMT - ĐHBKHN
72
Thời gian tính trung bình của QS
QuickSort Average Case
NỘI DUNG 5.5. Sắp xếp vun đống (Heap Sort)

• Thời gian tính trung bình = 5.1. Bài toán sắp xếp 5.5.1. Cấu trúc dữ liệu đống (heap)
5.2. Ba thuật toán sắp xếp cơ bản 5.5.2. Sắp xếp vun đống
 (thời gian phân đoạn kích thước i)(xác suất phân đoạn có kích thước i)
5.5.3. Hàng đợi có ưu tiên (priority queue)
• Trong tình huống ngẫu nhiên, tất cả các kích thước là đồng khả 5.3. Sắp xếp trộn (Merge Sort)
năng - xác suất chính là 1/N 5.4. Sắp xếp nhanh (Quick Sort)
T ( N ) = T (i ) + T ( N − i −1) + cN 5.5. Sắp xếp vun đống (Heap Sort)
E (T ( N )) =  i =0 (1/ N )  E (T (i)) + E (T ( N − i − 1) ) + cN 
N −1
5.6. Cận dưới cho độ phức tạp tính toán của bài toán sắp xếp
E (T ( N ))  (2 / N )  i =0  E (T (i) ) + cN 
N −1
5.7. Các phương pháp sắp xếp đặc biệt

• Giải công thức đệ qui này ta thu được


E(T(N)) = O(N log N).
73 NGUYỄN ĐỨC NGHĨA 74 NGUYỄN ĐỨC NGHĨA 75
Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN

5.5.1. The Heap Data Structure Biểu diễn đống bởi mảng Ví dụ đống
• Định nghĩa: Đống (heap) là cây nhị phân gần hoàn chỉnh có 2 • Đống có thể cất giữ trong mảng A.
1
parent(i) = i/2
tính chất: – Gốc của cây là A[1] 0
16 left-child(i) = 2i
– Tính cấu trúc: tất cả các mức đều là đầy, ngoại trừ mức cuối cùng, – Con trái của A[i] là A[2*i] right-child(i) = 2i +1
mức cuối được điền từ trái sang phải. 2 3
– Con phải của A[i] là A[2*i + 1]
– Tính có thứ tự hay tính chất đống : với mỗi nút x 1 14 10
Parent(x) ≥ x. – Cha của A[i] là A[ i/2 ]

• Cây được cài đặt bởi mảng A[i] có độ dài length[A]. Số lượng – Heapsize[A] ≤ length[A] 4 5 6 7

phần tử là heapsize[A] • Các phần tử trong mảng con 2 8 7 9 3


8 Từ tính chất đống suy ra: A[(n/2+1) .. n] là các lá
“Gốc chứa phần tử lớn nhất của đống!” 8 9
7 4 parent(i) = i/2 10

5 2 Như vậy có thể nói: left-child(i) = 2i 3 2 4 1 1 2 3 4 5 6 7 8 9 10


Đống là cây nhị phân được điền theo thứ tự right-child(i) = 2i +1 16 14 10 8 7 9 3 2 4 1
Heap
NGUYỄN ĐỨC NGHĨA 76 NGUYỄN ĐỨC NGHĨA 77 NGUYỄN ĐỨC NGHĨA 78
Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN

Hai dạng đống Bổ sung và loại bỏ nút Các phép toán đối với đống
Adding/Deleting Nodes Operations on Heaps

• Đống max - Max-heaps (Phần tử lớn nhất ở gốc), có tính chất • Nút mới được bổ sung vào mức đáy (từ trái sang phải) • Khôi phục tính chất max-heap (Vun lại đống)
max-heap: • Các nút được loại bỏ khỏi mức đáy (từ phải sang trái) – Max-Heapify
– với mọi nút i, ngoại trừ gốc:
A[parent(i)] ≥ A[i]
• Tạo max-heap từ một mảng không được sắp xếp
– Build-Max-Heap
• Đống min - Min-heaps (phần tử nhỏ nhất ở gốc), có tính chất
min-heap:
– với mọi nút i, ngoại trừ gốc:
A[parent(i)] ≤ A[i]
• Phần dưới đây ta sẽ chỉ xét đống max (max-heap). Đống min
được xét hoàn toàn tương tự.
NGUYỄN ĐỨC NGHĨA NGUYỄN ĐỨC NGHĨA NGUYỄN ĐỨC NGHĨA
Create PDF files without this message by purchasing79novaPDF printer (http://www.novapdf.com)
Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN
80
Bộ môn KHMT - ĐHBKHN
81
Khôi phục tính chất đống Ví dụ Thuật toán khôi phục tính chất đống

• Giả sử có nút i với giá trị bé hơn con của nó • Giả thiết: Max-Heapify(A, i, n)
– Giả thiết là: Cây con trái và Cây con phải của i đều là max-heaps – Cả hai cây con trái // n = heapsize[A]
A[2]  A[4]
• Để loại bỏ sự vi phạm này ta tiến hành như sau: và phải của i đều là 1. l  left-child(i)
– Đổi chỗ với con lớn hơn
max-heaps 2. r  right-child(i)
– A[i] có thể bé hơn 3. if (l ≤ n) and (A[l] > A[i])
– Di chuyển xuống theo cây các con của nó
– Tiếp tục quá trình cho đến khi nút không còn bé hơn con A[2] vi phạm tính chất đống A[4] vi phạm 4. then largest  l
5. else largest  i
6. if (r ≤ n) and (A[r] > A[largest])
7. then largest  r
A[4]  A[9] 8. if largest != i
9. then Exchange(A[i],A[largest])
10. Max-Heapify(A,largest,n)
Tính chất đống được khôi phục

NGUYỄN ĐỨC NGHĨA 82 NGUYỄN ĐỨC NGHĨA 83 NGUYỄN ĐỨC NGHĨA 84


Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN

Thời gian tính của MAX-HEAPIFY Xây dựng đống (Building a Heap) Ví dụ: A: 4 1 3 2 16 9 10 14 8 7

i =1 5 i= 4 i =1 3
• Ta nhận thấy rằng: • Biến đổi mảng A[1 … n] thành max-heap (n = length[A]) 1

4 4 4
– Từ nút i phải di chuyển theo đuờng đi xuống phía dưới của cây. Độ dài • Vì các phần tử của mảng con A[(n/2+1) .. n] là các lá 2 3 2 3 2 3
của đường đi này không vượt quá độ dài đường đi từ gốc đến lá, nghĩa 1 3 1 3 1 3
là khôngvượt quá h.
• Do đó để tạo đống ta chỉ cần áp dụng MAX-HEAPIFY đối với 4 5 6 7 4 5 6 7 4 5 6 7

2 16 9 10 8 2 16 9 10 8 14 16 9 10
– Ở mỗi mức phải thực hiện 2 phép so sánh.
các phần tử từ 1 đến n/2 8 9 10 9 10 9 10

14 8 7 14 8 7 2 8 7
– Do đó tổng số phép so sánh không vượt quá 2h. Alg: Build-Max-Heap(A) 1

4
– Vậy, thời gian tính là O(h) hay O(log n). i=2 i=1
1. n = length[A] 2 3
1 1 1

• Kết luận: Thời gian tính của MAX-HEAPIFY là O(log n) 1 3 4 4 16


2. for i ← n/2 downto 1 4 5 6 7

• Nếu viết trong ngôn ngữ chiều cao của đống, thì thời gian này 8
2 9 10
16 9 10 2

1 10
3

16
2

10
3

14
2 3

10
3. do Max-Heappify(A, i, n)
là O(h) 14 8 7 4 5 6 7 4 5 6 7 4 5 6 7

8
14 9 10
16 9 3 8
14 9 10
7 9 3 8
8 9 10
7 9 3
A: 4 1 3 2 16 9 10 14 8 7 2 8 7 2 8 1 2 4 1

NGUYỄN ĐỨC NGHĨA 85 NGUYỄN ĐỨC NGHĨA 86 NGUYỄN ĐỨC NGHĨA 87


Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN

Ví dụ: Build-Min-Heap Ví dụ: Build-Min-Heap Build-Min-Heap

size = 26 87 size = 26 87 size = 26 87

43 68 43 68 43 68

6 77 33 9 6 77 33 9 6 77 33 9

13 13
11 19 99 6 23 89 2 14 11 19 99 6 23 89 2 14 11 19 99 6 23 89 2 14

Bắt đầu từ phần


1 5 27 35 7 42 12 71 3 67 22 1 5 27 35 7 42 12 71 3 67 22 1 5 27 35 7 42 12 71 3 67 22 Vun lại đống
tử ở vị trí n/2

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com)
Build-Min-Heap Build-Min-Heap Build-Min-Heap

size = 26 87 size = 26 87 size = 26 87

43 68 43 68 43 68

6 77 33 9 6 77 33 9 6 77 33 9

13 13 13
11 19 99 6 23 22 2 14 11 19 99 6 23 22 2 14 11 19 99 6 3 22 2 14

1 5 27 35 7 42 12 71 3 67 89 Vun lại đống 1 5 27 35 7 42 12 71 3 67 89 Vun lại đống 1 5 27 35 7 42 12 71 23 67 89 Vun lại đống

Build-Min-Heap Build-Min-Heap Build-Min-Heap

size = 26 87 size = 26 87 size = 26 87

43 68 43 68 43 68

6 77 33 9 6 77 33 9 6 77 33 9

13 13 13
11 19 99 6 3 22 2 14 11 19 99 6 3 22 2 14 11 19 7 6 3 22 2 14

1 5 27 35 7 42 12 71 23 67 89 Vun lại đống 1 5 27 35 7 42 12 71 23 67 89 Vun lại đống 1 5 27 35 99 42 12 71 23 67 89 Vun lại đống

Build-Min-Heap Build-Min-Heap Build-Min-Heap

size = 26 87 size = 26 87 size = 26 87

43 68 43 68 43 68

6 77 33 9 6 77 33 9 6 77 33 9

13 13 13
11 19 7 6 3 22 2 14 11 19 7 6 3 22 2 14 1 19 7 6 3 22 2 14

1 5 27 35 99 42 12 71 23 67 89 Vun lại đống 1 5 27 35 99 42 12 71 23 67 89 Vun lại đống 11 5 27 35 99 42 12 71 23 67 89 Vun lại đống

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com)
Build-Min-Heap Build-Min-Heap Build-Min-Heap

size = 26 87 size = 26 87 size = 26 87

43 68 43 68 43 68

6 77 33 9 6 77 33 2 6 77 33 2

13 13 13
1 19 7 6 3 22 2 14 1 19 7 6 3 22 9 14 1 19 7 6 3 22 9 14

11 5 27 35 99 42 12 71 23 67 89 Vun lại đống 11 5 27 35 99 42 12 71 23 67 89 Vun lại đống 11 5 27 35 99 42 12 71 23 67 89 Vun lại đống

Build-Min-Heap Build-Min-Heap Build-Min-Heap

size = 26 87 size = 26 87 size = 26 87

43 68 43 68 43 68

6 77 3 2 6 77 3 2 6 77 3 2

13 13 13
1 19 7 6 33 22 9 14 1 19 7 6 33 22 9 14 1 19 7 6 23 22 9 14

11 5 27 35 99 42 12 71 23 67 89 Vun lại đống 11 5 27 35 99 42 12 71 23 67 89 Vun lại đống 11 5 27 35 99 42 12 71 33 67 89

Build-Min-Heap Build-Min-Heap Build-Min-Heap

size = 26 87 size = 26 87 size = 26 87

43 68 43 68 43 68

6 77 3 2 6 6 3 2 6 6 3 2

13 13 13
1 19 7 6 23 22 9 14 1 19 7 77 23 22 9 14 1 19 7 77 23 22 9 14

11 5 27 35 99 42 12 71 33 67 89 Vun lại đống 11 5 27 35 99 42 12 71 33 67 89 Vun lại đống 11 5 27 35 99 42 12 71 33 67 89 Vun lại đống

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com)
Build-Min-Heap Build-Min-Heap Build-Min-Heap

size = 26 87 size = 26 87 size = 26 87

43 68 43 68 43 68

6 6 3 2 6 6 3 2 1 6 3 2

13 13 13
1 19 7 12 23 22 9 14 1 19 7 12 23 22 9 14 6 19 7 12 23 22 9 14

11 5 27 35 99 42 77 71 33 67 89 Vun lại đống 11 5 27 35 99 42 77 71 33 67 89 Vun lại đống 11 5 27 35 99 42 77 71 33 67 89 Vun lại đống

Build-Min-Heap Build-Min-Heap Build-Min-Heap

size = 26 87 size = 26 87 size = 26 87

43 68 43 68 43 68

1 6 3 2 1 6 3 2 1 6 3 2

13 13 13
6 19 7 12 23 22 9 14 5 19 7 12 23 22 9 14 5 19 7 12 23 22 9 14

11 5 27 35 99 42 77 71 33 67 89 Vun lại đống 11 6 27 35 99 42 77 71 33 67 89 Vun lại đống 11 6 27 35 99 42 77 71 33 67 89 Vun lại đống

Build-Min-Heap Build-Min-Heap Build-Min-Heap

size = 26 87 size = 26 87 size = 26 87

43 2 43 2 43 2

1 6 3 68 1 6 3 68 1 6 3 9

13 13 13
5 19 7 12 23 22 9 14 5 19 7 12 23 22 9 14 5 19 7 12 23 22 68 14

11 6 27 35 99 42 77 71 33 67 89 Vun lại đống 11 6 27 35 99 42 77 71 33 67 89 Vun lại đống 11 6 27 35 99 42 77 71 33 67 89 Vun lại đống

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com)
Build-Min-Heap Build-Min-Heap Build-Min-Heap

size = 26 87 size = 26 87 size = 26 87

43 2 1 2 1 2

1 6 3 9 43 6 3 9 43 6 3 9

13 13 13
5 19 7 12 23 22 68 14 5 19 7 12 23 22 68 14 5 19 7 12 23 22 68 14

11 6 27 35 99 42 77 71 33 67 89 Vun lại đống 11 6 27 35 99 42 77 71 33 67 89 Vun lại đống 11 6 27 35 99 42 77 71 33 67 89 Vun lại đống

Build-Min-Heap Build-Min-Heap Build-Min-Heap

size = 26 87 size = 26 87 size = 26 87

1 2 1 2 1 2

5 6 3 9 5 6 3 9 5 6 3 9

13 13 13
43 19 7 12 23 22 68 14 43 19 7 12 23 22 68 14 6 19 7 12 23 22 68 14

11 6 27 35 99 42 77 71 33 67 89 Vun lại đống 11 6 27 35 99 42 77 71 33 67 89 Vun lại đống 11 43 27 35 99 42 77 71 33 67 89 Vun lại đống

Build-Min-Heap Build-Min-Heap Build-Min-Heap

size = 26 87 size = 26 1 size = 26 1

1 2 87 2 87 2

5 6 3 9 5 6 3 9 5 6 3 9

13 13 13
6 19 7 12 23 22 68 14 6 19 7 12 23 22 68 14 6 19 7 12 23 22 68 14

11 43 27 35 99 42 77 71 33 67 89 Vun lại đống 11 43 27 35 99 42 77 71 33 67 89 Vun lại đống 11 43 27 35 99 42 77 71 33 67 89 Vun lại đống

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com)
Build-Min-Heap Build-Min-Heap Build-Min-Heap

size = 26 1 size = 26 1 size = 26 1

5 2 5 2 5 2

87 6 3 9 87 6 3 9 6 6 3 9

13 13 13
6 19 7 12 23 22 68 14 6 19 7 12 23 22 68 14 87 19 7 12 23 22 68 14

11 43 27 35 99 42 77 71 33 67 89 Vun lại đống 11 43 27 35 99 42 77 71 33 67 89 Vun lại đống 11 43 27 35 99 42 77 71 33 67 89 Vun lại đống

Build-Min-Heap Build-Min-Heap Build-Min-Heap

size = 26 1 size = 26 1 size = 26 1

5 2 5 2 5 2

5 6 3 9 5 6 3 9 5 6 3 9

13 13 13
87 19 7 12 23 22 68 14 11 19 7 12 23 22 68 14 11 19 7 12 23 22 68 14

11 43 27 35 99 42 77 71 33 67 89 87 43 27 35 99 42 77 71 33 67 89 87 43 27 35 99 42 77 71 33 67 89
Vun lại đống Vun lại đống Kết thúc

Thời gian tính của Buil-Max-Heap Thời gian tính của Buid-Max-Heap Thời gian tính của Build-Max-Heap
h
• Heapify đòi hỏi thời gian O(h)  chi phí của Heapify ở nút i T (n) =  ni hi (Chi phí Heapify tại mức i) × (số lượng nút trên mức này)
Alg: Build-Max-Heap(A)
là tỷ lệ với chiều cao của nút i trên cây i =0
h h
1. n = length[A]  T (n) =  ni hi =  2 i (h − i ) = O (n)
h

i=0 i =0
=  2 i (h − i ) Thay giá trị của ni và hi tính được ở trên
2. for i ← n/2 downto 1 Chiều cao Mức Số lượng nút i =0
O(n) h−i h
h
=
1
3. do Max-Heapify(A, i, n) O(log n) h0 = 3 (log n) i=0 20
2 Nhân cả tử và mẫu với 2h và viết 2 i là
h −i 2 −i
i=0 2
h1 = 2 i=1 21 h
k
 Thời gian tính là: O(n log n) = 2h  k Đổi biến: k = h - i
k =0 2
• Đánh giá này là không sát ! h2 = 1 i=2 22

k
 n k
Thay tổng hữu hạn bởi tổng vô hạn
h3 = 0 i = 3 (log n) 23 k =0 2 và h = log n
= O(n) Tổng trên là nhỏ hơn 2
hi = h – i chiều cao của đống gốc tại mức i
ni = 2i số lượng nút ở mức i Thời gian tính của Build-Max-Heap: T(n) = O(n)
NGUYỄN ĐỨC NGHĨA NGUYỄN ĐỨC NGHĨA NGUYỄN ĐỨC NGHĨA
Create PDF files without this message by purchasing133novaPDF printer (http://www.novapdf.com)
Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN
134
Bộ môn KHMT - ĐHBKHN
135
5.5.2. Sắp xếp vun đống - Heapsort Ví dụ: A=[7, 4, 3, 1, 2] HeapSort(A)

• Sử dụng đống ta có thể phát triển thuật toán sắp xếp mảng.
• Sơ đồ của thuật toán được trình bày như sau: 1. Build-Max-Heap(A) O(n)
– Tạo đống max-heap từ mảng đã cho 2. for i ← length[A] downto 2
– Đổi chỗ gốc (phần tử lớn nhất) với phần tử cuối cùng trong mảng Max-Heapyfy(A, 1, 4) Max-Heapyfy(A, 1, 3) Max-Heapyfy(A, 1, 2) 3. do exchange A[1] ↔ A[i]
– Loại bỏ nút cuối cùng bằng cách giảm kích thước của đống đi 1 n-1 lần lặp
4. Max-Heapify(A, 1, i - 1) O(log n)
– Thực hiện Max-Heapify đối với gốc mới
– Lặp lại quá trình cho đến khi đống chỉ còn 1 nút
• Thời gian tính: O(n log n)
• Có thể chứng minh thời gian tính là Θ(n log n)
Max-Heapyfy(A, 1, 1)

NGUYỄN ĐỨC NGHĨA 136 NGUYỄN ĐỨC NGHĨA 137 NGUYỄN ĐỨC NGHĨA 138
Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN

Tổng kết:
Câu hỏi Có thể sắp xếp nhanh đến mức độ nào? Các thuật toán sắp xếp dựa trên phép so sánh

• Giả sử các số trong max-heap là phân biệt, phần tử lớn thứ hai • Heapsort, Mergesort, và Quicksort có thời gian O(n log n) là
nằm ở đâu? các thuật toán có thời gian tính tốt nhất trong các thuật toán Name Average Worst In place Stable
trình bày ở trên
Bubble sort — O(n²) Yes Yes
• Liệu có thể phát triển được thuật toán tốt hơn không?
• Câu trả lời là: "Không, nếu như phép toán cơ bản là phép so Selection sort O(n²) O(n²) Yes No
sánh". Insertion sort O(n + d) O(n²) Yes Yes

Merge sort O(n log n) O(n log n) No Yes

Heapsort O(n log n) O(n log n) Yes No

Quicksort O(n log n) O(n²) No No


• Ans: Con lớn hơn trong hai con của gốc

NGUYỄN ĐỨC NGHĨA 139 NGUYỄN ĐỨC NGHĨA 140 NGUYỄN ĐỨC NGHĨA 141
Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN Bộ môn KHMT - ĐHBKHN

QUESTIONS?

NGUYỄN ĐỨC NGHĨA


Create PDF files without this message by purchasing142novaPDF printer (http://www.novapdf.com)
Bộ môn KHMT - ĐHBKHN

You might also like