CTDL-01-Phan Tich Thuat Toan
CTDL-01-Phan Tich Thuat Toan
CTDL-01-Phan Tich Thuat Toan
(Algorithm Analysis)
Bài giảng môn Cấu trúc dữ liệu và giải thuật
Khoa Công nghệ thông tin
Trường Đại học Thủy Lợi
2
Nội dung
1. Phân tích thuật toán là gì?
2. Các ký hiệu tiệm cận
3. Tốc độ tăng của các hàm
4. Các ví dụ phân tích thuật toán
3
Ký hiệu O
f(n) = O(g(n))
khi và chỉ khi c > 0 và n0 > 0 sao cho f(n)
cg(n) n n0
cg(n)
f(n)
n0
10
Ký hiệu
f(n) = (g(n))
khi và chỉ khi c > 0 và n0 > 0 sao cho cg(n)
f(n) n n0
f(n)
cg(n)
f(n) bị chặn dưới bởi g(n)
theo nghĩa tiệm cận
n0
11
Ký hiệu
f(n) = (g(n))
khi và chỉ khi c1 > 0, c2 > 0 và n0 > 0 sao cho
c1g(n) f(n) c2g(n) n n0
c2g(n)
f(n)
f(n) có cùng tốc độ tăng
c1g(n) với g(n) theo nghĩa tiệm
cận
n0
12
Chú ý:
− Trong môn học này, khi viết hàm lôgarít mà không
chỉ rõ cơ số, ta ngầm hiểu cơ số là 2.
− Từ giờ trở đi, ta chỉ tập trung vào ký hiệu O.
15
Hàm Tên
c Hằng
log n Lôgarít
log2 n Lôgarít bình phương
n Tuyến tính
n log n
n2 Bậc hai
n3 Bậc ba
2n Hàm mũ
17
Vòng lặp
1 for (i = 0; i < n; i++)
2 {
3 x = a[i] / 2;
4 a[i] = x + 1;
5 }
• Có 4 thao tác cơ bản ở các dòng 3 và 4, gồm 2 phép gán, 1 phép
chia và 1 phép cộng.
• Cả 4 thao tác cơ bản đó được lặp lại n lần.
• Thời gian chạy: t(n) = 4n = O(n)
Chú ý: Ở đây, ta bỏ qua 3 thao tác cơ bản điều khiển quá trình lặp
ở dòng 1 là gán giá trị cho i, i++ và so sánh i với n. Kết quả phân
tích thuật toán sẽ không thay đổi nếu tính thêm cả 3 thao tác cơ
bản đó.
21
• Có 5 thao tác cơ bản ở các dòng 3, 4, 5, gồm 2 phép gán, 1 phép chia, 1
phép cộng và 1 phép so sánh
• Không thể đếm chính xác số lần thực hiện 5 thao tác cơ bản đó vì ta không
biết khi nào điều kiện a[i] > 10 xảy ra.
• Trong trường hợp tồi nhất, tức là điều kiện a[i] > 10 xảy ra ở bước lặp cuối
cùng hoặc không bao giờ xảy ra, cả 5 thao tác cơ bản được lặp lại n lần.
• Thời gian chạy trong trường hợp tồi nhất: t(n) = 5n = O(n)
22
• Chỉ cần cộng thời gian chạy của các vòng lặp.
• Thời gian chạy tổng thể: t(n) = 3n + 5n = 8n = O(n)
23
Hàm đệ quy
1 long factorial(int n)
2 {
3 if (n <= 1)
4 return 1;
5 else
6 return n * factorial(n - 1);
7 }
• Nếu n = 1, chỉ mất 1 phép so sánh n <= 1 ở dòng 3.
• Nếu n > 1:
− Dòng 3 có 1 phép so sánh (và bị sai nên nhảy đến dòng 6).
− Dòng 6 có 1 phép nhân, 1 phép trừ và 1 lời gọi hàm đệ quy
tốn thời gian t(n-1).
26
• Trong trường hợp tồi nhất, tức là x nằm ở cuối mảng hoặc
x không có trong mảng, ta phải thực hiện n phép so sánh
a[i] == x.
• Thời gian chạy trong trường hợp tồi nhất: t(n) = n = O(n)
28
a 2 4 5 8 11 15 20
x = 8?
a 2 4 5 8 11 15 20
x = 15?
a 2 4 5 8 11 15 20
x = 11?
30
Bài tập 1
Xét các thuật toán có thời gian chạy như bên dưới. Hỏi
mỗi thuật toán chậm đi bao nhiêu lần khi gấp đôi kích
thước đầu vào?
a. n
b. n2
c. n3
d. 100n2
e. n log n
f. 2n
33
Bài tập 2
Sắp xếp các hàm sau đây theo thứ tự tăng dần của tốc
độ tăng; nghĩa là, hàm f(n) sẽ được xếp trước hàm g(n)
nếu f(n) = O(g(n)).
f1(n) = n2,5
f2(n) =
f3(n) = n + 10
f4(n) = 10n
f5(n) = 100n
f6(n) = n2 log n
34
Bài tập 3
Phân tích thời gian chạy (dùng ký hiệu O) của thuật
toán tìm phần tử lớn nhất.
max a0
for i 1 to n-1
if (ai > max)
max ai
35
Bài tập 4
Phân tích thời gian chạy (dùng ký hiệu O) của các đoạn
chương trình C++ sau đây. (không tính các thao tác điều
khiển của vòng lặp)
(a) sum = 0;
for (i = 0; i < n; i++)
sum++;
(b) sum = 0;
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
sum++;
36
Bài tập 4
Phân tích thời gian chạy (dùng ký hiệu O) của các đoạn
chương trình C++ sau đây. (không tính các thao tác điều
khiển của vòng lặp)
(c) sum = 0;
for (i = 0; i < n; i++)
for (j = 0; j < n*n; j++)
sum++;
(d) sum = 0;
for (i = 0; i < n; i++)
for (j = 0; j < i; j++)
sum++;
37
Bài tập 4
Phân tích thời gian chạy (dùng ký hiệu O) của các đoạn chương
trình C++ sau đây. (không tính các thao tác điều khiển của vòng
lặp)
(e) sum = 0;
for (i = 0; i < n; i++)
for (j = 0; j < i*i; j++)
for (k = 0; k < j; k++)
sum++;
(f) sum = 0;
for (i = 0; i < n; i++)
for (j = 0; j < i*i; j++)
if (j % i == 0)
for (k = 0; k < j; k++)
sum++;