Lecture 8 - Algorithms - Part1 - VI
Lecture 8 - Algorithms - Part1 - VI
1
Nội dung chính
1. Chia để trị
2. Quy hoạch động
3. Các thuật toán tham ăn
2
Chia để trị
(Divide and Conque)
3
Thuật toán tìm kiếm nhị
phân
Bài toán: Cho một danh sách A được sắp xếp theo thứ tự
tăng dần. Viết hàm để kiểm tra có phần tử X trong dãy A?
Algorithm:
➢ Step 1:
❖ If A rỗng, return False
❖ Else: so sánh X với Y (là phần tử ở giữa dãy A).
➢ Step 2:
❖ If X = Y, return True.
❖ If X < Y, tìm kiếm dãy bên trái của A
❖ If X > Y, tìm kiếm dãy bên phải của A
Độ phức tạp: O(log n)
4
Ví dụ
1 1 1 1 1
0 1 3 4 5 7 8 9
1 4 6 8 9
l m r
1 1 1 1 1
0 1 3 4 5 7 8 9
1 4 6 8 9
l m r
1 1 1 1 1
0 1 3 4 5 7 8 9
1 4 6 8 9
l m r
1 1 1 1 1
0 1 3 4 5 7 8 9
1 4 6 8 9
l=m
=r
5
Sắp xếp trộn
7 2|9 4 → 2 4 7 9
7|2 → 2 7 9|4 → 4 9
6
Sắp xếp trộn
7
Trộn 2 dãy đã sắp xếp
Algorithm merge(A, B)
➢ Bước trị của thuật Input sequences A and B with
toán sắp xếp trộn là n/2 elements each
trộn hai dãy đã sắp Output sorted sequence of A ∪ B
xếp A và B thành S ← empty sequence
một dãy được sắp
while ¬A.isEmpty() ∧ ¬B.isEmpty()
xếp S lưu trữ các
if A.first().element() <
phần tử của cả A và
B.first().element()
B
➢ Độ phức tạp: O(n) S.insertLast(A.remove(A.first()));
else
S.insertLast(B.remove(B.first()));
while ¬A.isEmpty()
S.insertLast(A.remove(A.first()));
while ¬B.isEmpty()
S.insertLast(B.remove(B.first())); 8
return S;
Ví dụ
➢Phân hoạch
7 2 9 4|3 8 6 1 → 1 2 3 4 6 7 8 9
7 2 9 4 → 2 4 7 9 3 8 6 1 → 1 3 8 6
7 2 → 2 7 9 4 → 4 9 3 8 → 3 8 6 1 → 1 6
7→ 2→ 9→ 4→ 3→ 8→ 6→ 1→
7 2 9 4 3 8 6 1
9
Ví dụ (cont.)
➢Lời gọi đệ quy, phân hoạch
7 2 9 4|3 8 6 1 → 1 2 3 4 6 7 8 9
7 2|9 4→ 2 4 7 9 3 8 6 1 → 1 3 8 6
7 2 → 2 7 9 4 → 4 9 3 8 → 3 8 6 1 → 1 6
7→ 2→ 9→ 4→ 3→ 8→ 6→ 1→
7 2 9 4 3 8 6 1
10
Ví dụ (cont.)
➢Lời gọi đệ quy, Phân hoạch
7 2 9 4|3 8 6 1 → 1 2 3 4 6 7 8 9
7 2|9 4→ 2 4 7 9 3 8 6 1 → 1 3 8 6
7|2→2 7 9 4 → 4 9 3 8 → 3 8 6 1 → 1 6
7→ 2→ 9→ 4→ 3→ 8→ 6→ 1→
7 2 9 4 3 8 6 1
11
Ví dụ (cont.)
➢Lời gọi đệ quy, Phân hoạch
7 2 9 4|3 8 6 1 → 1 2 3 4 6 7 8 9
7 2|9 4→ 2 4 7 9 3 8 6 1 → 1 3 8 6
7|2→2 7 9 4 → 4 9 3 8 → 3 8 6 1 → 1 6
2→ 9→ 4→ 3→ 8→ 6→ 1→
7→7
2 9 4 3 8 6 1
12
Ví dụ (cont.)
➢Lời gọi đệ quy, Phân hoạch
7 2 9 4⏐3 8 6 1 → 1 2 3 4 6 7 8 9
7 2⏐9 4→ 2 4 7 9 3 8 6 1 → 1 3 8 6
7⏐2→2 7 9 4 → 4 9 3 8 → 3 8 6 1 → 1 6
7→ 9→ 4→ 3→ 8→ 6→ 1→
2→2
7 9 4 3 8 6 1
13
Ví dụ (cont.)
➢Trộn
7 2 9 4|3 8 6 1 → 1 2 3 4 6 7 8 9
7 2|9 4→ 2 4 7 9 3 8 6 1 → 1 3 8 6
7|2→2 7 9 4 → 4 9 3 8 → 3 8 6 1 → 1 6
9→ 4→ 3→ 8→ 6→ 1→
7→7 2→2
9 4 3 8 6 1
14
Ví dụ (cont.)
➢ Lời gọi đệ quy, …, Trường hợp cơ sở, trộn
7 2 9 4|3 8 6 1 → 1 2 3 4 6 7 8 9
7 2|9 4→ 2 4 7 9 3 8 6 1 → 1 3 8 6
7|2→2 7 9 4 → 4 9 3 8 → 3 8 6 1 → 1 6
3→ 8→ 6→ 1→
7→7 2→2 9→9 4→4
3 8 6 1
15
Ví dụ (cont.)
➢Trộn
7 2 9 4|3 8 6 1 → 1 2 3 4 6 7 8 9
7 2|9 4→ 2 4 7 9 3 8 6 1 → 1 3 8 6
7|2→2 7 9 4 → 4 9 3 8 → 3 8 6 1 → 1 6
3→ 8→ 6→ 1→
7→7 2→2 9→9 4→4
3 8 6 1
16
Ví dụ (cont.)
➢Lời gọi đệ quy, …, trộn, trộn
7 2 9 4|3 8 6 1 → 1 2 3 4 6 7 8 9
7 2|9 4→ 2 4 7 9 3 8 6 1 → 1 3 6 8
7|2→2 7 9 4 → 4 9 3 8 → 3 8 6 1 → 1 6
7 2⏐9 4→ 2 4 7 9 3 8 6 1 → 1 3 6 8
7⏐2→2 7 9 4 → 4 9 3 8 → 3 8 6 1 → 1 6
7→ 9→ 4→ 3→ 8→ 6→ 1→
2→2
7 9 4 3 8 6 1
18
Phân tích độ phức tạp
➢ Độ cao của cây h =log n
❖ Tại mỗi lời gọi đệ quy, chúng ta chia đôi dãy,
➢ Số lượng công việc thực hiện tại các đỉnh có độ sau i là O(n)
❖ Chúng ta phân hoạch và trộn 2i chuỗi có kích thước n/2i
❖ Chúng ta tạo ra 2i+1 lời gọi đệ quy
➢ Do đó, tổng thời gian thực hiện (độ phức tạp): O(n log n)
1 2 n/2
i 2i n/2i
19
… … …
Tóm tắt các thuật toán sắp
xếp
Expected
Algorithm Notes
time
• slow
selection-sort O(n2) • for small data sets (< 1K)
• slow
insertion-sort O(n2) • for small data sets (< 1K)
• fast
heap-sort O(n log n) • for large data sets (1K —
1M)
• fast
merge-sort O(n log n) • for huge data sets (> 1M)
• fast and most common in
Quick-sort O(n log n) practice
• for huge data sets (> 1M)
20
Bài tập 1
Minh họa quá trình thực hiện của thuật toán sắp xếp
trộn trên dãy sau
3, 13, 89, 34, 21, 44, 99, 56, 9
21
Quick-Sort
• Quick-sort là thuật toán
sătps xếp ngẫu nhiên dựa
x
trên chiến lược chia và trị:
– Chia: Chọn ngẫu nhiên một
phần tử x (gọi là khoá) và
phân hoạch S vào
• L chứa các phần tử bé hơn x x
• E chứa các phần tử bằng x
• G chứa các phần tử lớn hơn x L E G
– Đệ quy: Sắp xếp L và G
– Trị: Kết hợp L, E và G
22
Ví dụ
Cho một mảng gồm n phần tử
40 20 10 80 60 50 7 30 100
23
Phần tử khoá
Sử dụng phần tử đầu tiên làm khoá
40 20 10 80 60 50 7 30 100
24
Chỉ số khoá = 0 40 20 10 80 60 50 7 30 100
csd csc
25
1. While data[csd] <= data[chisokhoa]
++csd;
chisokhoa =0 40 20 10 80 60 50 7 30 100
csd csc
26
1. While (data[csd] <= data[chisokhoa])
++csd;
Chisokhoa=0 40 20 10 80 60 50 7 30 100
csd csc
27
1. While (data[csd] <= data[chisokhoa])
++csd;
Chisokhoa=0 40 20 10 80 60 50 7 30 100
csd csc
28
1. While (data[csd] <= data[chisokhoa])
++csd;
2. While data[too_small_index] > data[pivot]
--csc;
Chisokhoa=0 40 20 10 80 60 50 7 30 100
csd csc
29
1. While (data[csd] <= data[chisokhoa])
++csd;
2. While data[too_small_index] > data[pivot]
--csc;
Chisokhoa=0 40 20 10 80 60 50 7 30 100
csd csc
30
1. While (data[csd] <= data[chisokhoa])
++csd;
2. While data[too_small_index] > data[pivot]
--csc;
3. If csd<csc
swap data[csd] and data[csc]
Chisokhoa=0 40 20 10 80 60 50 7 30 100
csd csc
31
1. While (data[csd] <= data[chisokhoa])
++csd;
2. While data[too_small_index] > data[pivot]
--csc;
3. If csd<csc
swap data[csd] and data[csc]
4. While csc> csd go to 1.
Chisokhoa=0 40 20 10 30 60 50 7 80 100
csd csc
32
1. While (data[csd] <= data[chisokhoa])
++csd;
2. While data[too_small_index] > data[pivot]
--csc;
3. If csd<csc
swap data[csd] and data[csc]
4. While csc> csd go to 1.
Chisokhoa=0 40 20 10 30 60 50 7 80 100
csd csc
33
1. While (data[csd] <= data[chisokhoa])
++csd;
2. While data[too_small_index] > data[pivot]
--csc;
3. If csd<csc
swap data[csd] and data[csc]
4. While csc> csd go to 1.
Chisokhoa=0 40 20 10 30 60 50 7 80 100
csd csc
34
1. While (data[csd] <= data[chisokhoa])
++csd;
2. While data[too_small_index] > data[pivot]
--csc;
3. If csd<csc
swap data[csd] and data[csc]
4. While csc> csd go to 1.
Chisokhoa=0 40 20 10 30 60 50 7 80 100
csd csc
35
1. While (data[csd] <= data[chisokhoa])
++csd;
2. While data[too_small_index] > data[pivot]
--csc;
3. If csd<csc
swap data[csd] and data[csc]
4. While csc> csd go to 1.
Chisokhoa=0 40 20 10 30 60 50 7 80 100
csd csc
36
1. While (data[csd] <= data[chisokhoa])
++csd;
2. While data[too_small_index] > data[pivot]
--csc;
3. If csd<csc
swap data[csd] and data[csc]
4. While csc> csd go to 1.
chisokhoa= 0 40 20 10 30 60 50 7 80 100
csd csc
37
1. While (data[csd] <= data[chisokhoa])
++csd;
2. While data[too_small_index] > data[pivot]
--csc;
3. If csd<csc
swap data[csd] and data[csc]
4. While csc> csd go to 1.
Chisokhoa=0 40 20 10 30 60 50 7 80 100
csd csc
38
1. While (data[csd] <= data[chisokhoa])
++csd;
2. While data[too_small_index] > data[pivot]
--csc;
3. If csd<csc
swap data[csd] and data[csc]
4. While csc> csd go to 1.
Chisokhoa=0 40 20 10 30 7 50 60 80 100
csd csc
39
1. While (data[csd] <= data[chisokhoa])
++csd;
2. While data[too_small_index] > data[pivot]
--csc;
3. If csd<csc
swap data[csd] and data[csc]
4. While csc> csd go to 1.
Chisokhoa=0 40 20 10 30 7 50 60 80 100
csd csc
40
1. While (data[csd] <= data[chisokhoa])
++csd;
2. While data[too_small_index] > data[pivot]
--csc;
3. If csd<csc
swap data[csd] and data[csc]
4. While csc> csd go to 1.
chisokhoa = 0 40 20 10 30 7 50 60 80 100
csd csc
41
1. While (data[csd] <= data[chisokhoa])
++csd;
2. While data[too_small_index] > data[pivot]
--csc;
3. If csd<csc
swap data[csd] and data[csc]
4. While csc> csd go to 1.
chisokhoa = 0 40 20 10 30 7 50 60 80 100
csd csc
42
1. While (data[csd] <= data[chisokhoa])
++csd;
2. While data[too_small_index] > data[pivot]
--csc;
3. If csd<csc
swap data[csd] and data[csc]
4. While csc> csd go to 1.
chisokhoa= 0 40 20 10 30 7 50 60 80 100
csd csc
43
1. While (data[csd] <= data[chisokhoa])
++csd;
2. While data[too_small_index] > data[pivot]
--csc;
3. If csd<csc
swap data[csd] and data[csc]
4. While csc> csd go to 1.
chisokhoa = 0 40 20 10 30 7 50 60 80 100
csd csc
44
1. While (data[csd] <= data[chisokhoa])
++csd;
2. While data[too_small_index] > data[pivot]
--csc;
3. If csd<csc
swap data[csd] and data[csc]
4. While csc> csd go to 1.
chisokhoa = 0 40 20 10 30 7 50 60 80 100
csd csc
45
1. While (data[csd] <= data[chisokhoa])
++csd;
2. While data[too_small_index] > data[pivot]
--csc;
3. If csd<csc
swap data[csd] and data[csc]
4. While csc> csd go to 1.
chisokhoa = 0 40 20 10 30 7 50 60 80 100
csd csc
46
1. While (data[csd] <= data[chisokhoa])
++csd;
2. While data[too_small_index] > data[pivot]
--csc;
3. If csd<csc
swap data[csd] and data[csc]
4. While csc> csd go to 1.
chisokhoa = 0 40 20 10 30 7 50 60 80 100
csd csc
47
1. While (data[csd] <= data[chisokhoa])
++csd;
2. While data[too_small_index] > data[pivot]
--csc;
3. If csd<csc
swap data[csd] and data[csc]
4. While csc> csd go to 1.
5. Swap data[csc] and data[chisokhoa]
chisokhoa = 0 40 20 10 30 7 50 60 80 100
csd csc
48
1. While (data[csd] <= data[chisokhoa])
++csd;
2. While data[too_small_index] > data[pivot]
--csc;
3. If csd<csc
swap data[csd] and data[csc]
4. While csc> csd go to 1.
5. Swap data[csc] and data[chisokhoa]
khisokhoa = 4 7 20 10 30 40 50 60 80 100
csd csc
49
Kết quả phân hoạch
7 20 10 30 40 50 60 80 100
50
Đệ quy: QuickSort các mảng con
7 20 10 30 40 50 60 80 100
51
Summary of Sorting
Algorithms
Expected
Algorithm Notes
time
• slow
selection-sort O(n2) • for small data sets (< 1K)
• slow
insertion-sort O(n2) • for small data sets (< 1K)
• fast
heap-sort O(n log n) • for large data sets (1K —
1M)
• fast
merge-sort O(n log n) • for huge data sets (> 1M)
• fast and most common in
Quick-sort O(n log n) practice
• for huge data sets (> 1M)
52
Exercise 2
53