Professional Documents
Culture Documents
Quick Sort
• Được phát triển bởi Tony Hoare vào năm 1959
• Thuật toán Quicksort dựa trên chiến lược chia để trị
(divide-and-conquer).
DSA 3
DSA 2 DSA 4
1
04/05/2022
DSA 5 DSA 7
DSA 6 DSA 8
2
04/05/2022
DSA 9 DSA 11
3
04/05/2022
j i j i
1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8
4 2 1 5 8 6 12 15 1 2 4 5 6 8 12 15
DSA 13 DSA 15
DSA 14 DSA 16
4
04/05/2022
DSA 17 DSA 19
5
15
20 35
(b)
30 25 40 45
55 50
DSA 18 DSA 20
5
04/05/2022
RIGHT(i) 2 4 1
30 25 40 45
2 8 5
0 1 2 3 4 5 6 7 8 9
return 2i+2
55 50 Đáp án: (a), (b) 16 14 10 8 7 9 3 2 4 1
DSA 21 DSA 23
Binary Heap thường được biểu diễn bởi một mảng (array-based • Array-based binary heap phải thỏa mãn tính chất heap (heap
property):
binary heap) thay vì một cây nhị phân (pointer-based binary heap).
• Với Binary Max-Heap: Tất cả các node i (không kể node gốc) thỏa A[i]
≤ A[PARENT(i)].
0 1 2 3 4 5 6 7 8 9 • Với Binary Min-Heap: Tất cả các node i (không kể node gốc) thỏa A[i] ≥
A[PARENT(i)]. 0
16 14 10 8 7 9 3 2 4 1 16
1 2
0
14 10
16
3 4 5 6
1 2
8 7 9 3
14 10
7 8 9
3 4 5 6
2 4 1
8 7 9 3 0 1 2 3 4 5 6 7 8 9
7 8 9 16 14 10 8 7 9 3 2 4 1
2 4 1
DSA 22 DSA 24
6
04/05/2022
Bài tập: (tt) Duy trì tính chất Heap: Ví dụ trên cây Max-Heap
Cho biết dãy nào sau đây thỏa tính chất Heap.
a) 20, 18, 15, 17, 5, 10 HEAPIFY(A, 10, 1)
DSA 25 DSA 27
Duy trì tính chất Heap: HEAPIFY hay Re-Heap Xây dựng cây Heap: BUILD-HEAP
• HEAPIFY is to let the value at A[i] "float down" in the heap so that • BUILD-HEAP thực hiện chuyển đổi dãy A[0 .. n-1] thành dãy có tính chất heap
the subtree rooted at i becomes a heap:
(array-based binary heap). Với N là số lượng phần tử của A, ký hiệu length[A]=n.
• Thuật toán:
Quá trình đó sẽ sử dụng HEAPIFY trên các phần tử của mảng. Trong đó:
HEAPIFY(A, heap-size, i)
• Các phần tử từ A[n/2] → A[n-1] là các node lá của cây nên không cần xét.
1. l <- LEFT(i)
2. r <- RIGHT(i) • BUILD-HEAP sẽ thực hiện HEAPIFY tất cả các phần tử còn lại bắt đầu từ
3. largest <- i dưới lên trên (bottom-up manner). Nghĩa là từ A[n/2-1] ngược lên A[0].
4. if l < heap-size[A] and A[l] > A[i]
5. then largest <- l BUILD-HEAP(A)
6. if r < heap-size[A] and A[r] > A[largest] 1. heap-size[A] <- length[A]
7. then largest <- r 2. for i <- length[A]/2-1 downto 0 do
8. if largest ≠ i 3. HEAPIFY(A, heap-size, i)
9. then exchange A[i] <-> A[largest]
10. HEAPIFY(A, heap-size, largest )
DSA 26 DSA 28
7
04/05/2022
4
1 2
1 3
(3)
3 4 5 6
2 16 9 10
7 8 9
14 8 7
DSA 29 DSA 31
(5)
DSA 30 DSA 32
8
04/05/2022
0 1 2 3 4 5 6 7 8 9 • The heapsort algorithm then repeats this process for the heap
of size n-1 down to a heap of size 2.
Dãy ban đầu: 4 1 3 2 16 9 10 14 8 7
HEAPSORT(A)
The heap after BUILD-HEAP finishes : 1. BUILD-HEAP(A)
2. for i <- length[A]-1 downto 1 do
0 3. exchange A[0] <-> A[i]
16 4. heap-size[A] <- heap-size[A]-1
1 2
0 1 2 3 4 5 6 7 8 9 5. HEAPIFY(A, heap-size, 0)
14 10
hay: 16 14 10 8 7 9 3 2 4 1
3 4 5 6
DSA 33 DSA 35
bước 2 trên cho tới khi dãy heap còn 1 phần tử.
DSA 34 DSA 36
9
04/05/2022
14 10 14 10 8 10
for(int i = n/2-1; i>=0; i--) 3 4 5 6 3 4 5 6 3 4 5 6
} 2 4 1 2 4 16 2 14 16
0 0
1
void HeapSort(int a[], int n) { 2 2
(d) (e) (f) 1 2
int heapSize; 1 2 1
8
2
3
7 3
8 9
heapSize = n; 3 4 5 6 3 4 5
3 4
4 2 8 9
buildHeap(a, n); 4 7 1 3 4 7 1 9
3
4 1 3 2 16 9 10 14 8 7 1 7 8 9 4 7 8 9
10 14 16 10 14 16
0 (i) 1 (j) 1
4 1
2 3 2 3
1 2
1 3 4 7 8 9 4 7 8 9
3 4 5 6
10 14 16 10 14 16
2 16 9 10
7 8 9 1 2 3 4 7 8 9 10 14 16
14 8 7
The resulting sorted array A.
DSA 38 DSA 40
10
04/05/2022
2. Illustrate the operation of HEAPIFY(A,3,) on the array A= 1. Chọn trực tiếp - Selection Sort
(27, 17,3,16, 13, 10, 1,5,7, 12,4,8,9,0). 2. Đổi chỗ trực tiếp - Interchange Sort
3. The code for HEAPIFY is quite efficient in terms of constant 3. Nổi bọt - Bubble Sort
factors, except possibly for the recursive call in line 10,
which might cause some compilers to produce inefficient 4. Shaker Sort
code. Write an efficient HEAPIFY that uses an iterative 5. Chèn trực tiếp - Insertion Sort
control construct (a loop) instead of recursion.
6. Chèn nhị phân - Binary Insertion Sort
4. Illustrate the operation of BUILD-HEAP on the array A =
(5, 3, 17, l0, 84, 19, 6, 22, 9) 7. Shell Sort
5. Show that the running time of heapsort is Ω( nlgn). 8. Quick Sort
6. Illustrate the operation of HEAPSORT on the array 9. Heap Sort
A = (5, 13, 2, 25, 7, 17, 20, 8, 4) 10. Merge Sort
11. Radix Sort
DSA 41 DSA 43
• Thuật toán Mergesort áp dụng thuật toán chia để trị (divide and
• Lặp lại việc trộn (merge) để tạo ra các danh sách con mới có thứ
tự cho tới khi chỉ còn 1 danh sách con. Đây sẽ là danh sách được
sắp xếp.
DSA 42 DSA 44
11
04/05/2022
DSA 45 DSA 47
Top-down Merge Sort: Minh họa Top-down Merge Sort: Code C/C++ (tt)
void TopDownMerge(int* a, int l, int r) {
int *b, nb = r - l + 1; // Tạo mảng b lưu giá trị mảng a[l->r]
b = new int[nb];
Copy(b, a, l, r);
DSA 46 DSA 48
12
04/05/2022
DSA 49 DSA 51
Bottom-up Merge Sort: Minh họa Bottom-up Merge Sort: Code C/C++
void BottomUpMerge(int a[], int iLeft, int iRight, int iEnd, int b[]) {
int i = iLeft, j = iRight;
// While there are elements in the left or right runs...
for (int k = iLeft; k <= iEnd; k++)
// If left run head exists and is <= existing right run head.
if (i < iRight && (j > iEnd || a[i] <= a[j]))
b[k] = a[i++];
else b[k] = a[j++];
}
DSA 50 DSA 52
13
04/05/2022
DSA 53
DSA 54
14
04/05/2022
Radix Sort: Thuật toán (tt) Radix Sort: Minh họa (tt)
• Bước 1:// k cho biết chữ số dùng để phân loại hiện hành
• k = 0; // k = 0: hàng đơn vị; k = 1: hàng chục; …
• Bước 2: //Tạo các lô chứa các loại phần tử khác nhau
• Khởi tạo 10 lô B0, B1, …, B9 rỗng;
Radix Sort: Thuật toán (tt) Radix Sort: Minh họa (tt)
• Bước 3:
• For i = 0 .. n-1 do
• Đặt ai vào lô Bt với t: chữ số thứ k của ai;
• Bước 4:
• Nối B0, B1, …, B9 lại (theo đúng trình tự) thành a.
• Bước 5:
• k = k+1; Nếu k < m thì trở lại bước 2. Ngược lại: Dừng
15
04/05/2022
Radix Sort: Minh họa (tt) Radix Sort: Minh họa (tt)
Radix Sort: Minh họa (tt) Radix Sort: Code C/C++ (tt)
void RadixSort(int arr[], int n) {
// Find the maximum number to know number of digits
int m = GetMax(arr, n);
// Do counting sort for every digit. Note that instead of passing digit
// number, exp is passed. exp is 10^i where i is current digit number
for (int exp = 1; m / exp > 0; exp *= 10)
CountingSort(arr, n, exp);
}
int GetMax(int arr[], int n) {
int max = arr[0];
for (int i = 1; i < n; i++)
if (arr[i] > max)
max = arr[i];
return max;
}
DSA 64
16
04/05/2022
// Change count[i] so that count[i] now contains actual position of this digit in output[]
for (i = 1; i < 10; i++) count[i] += count[i - 1];
DSA 65 DSA 67
DSA 66 DSA 68
17
04/05/2022
DSA 69
DSA 72
18