You are on page 1of 83

KHOA CÔNG NGHỆ THÔNG TIN

MÔN HỌC: CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT

BÀI 1:
ĐẠI CƯƠNG VỀ CẤU TRÚC
DỮ LIỆU VÀ GIẢI THUẬT
I - MỤC TIÊU BÀI HỌC

- Hiểu các khái niệm về giải thuật, cấu trúc dữ


liệu, ngôn ngữ diễn tả giải thuật.

- Nắm và vận dụng phương pháp xây dựng giải


thuật (Thiết kế và đánh giá) cho các bài toán
đơn giản.

- Hiểu về đệ qui và các giải thuật đệ qui đơn


giản

Slide 2
II - KHÁI QUÁT NỘI DUNG BÀI HỌC

1.1. Khái niệm về giải thuật, mối liên hệ giữa


CTDL và GT
1.2. Cấu trúc dữ liệu và các vấn đề liên quan
1.3. Ngôn ngữ diễn đạt giải thuật
1.4. Thiết kế giải thuật
1.5. Phân tích độ phức tạp của giải thuật
1.6. Sơ lược về giải thuật đệ quy

Slide 3
1.1. Khái niệm về giải thuật, mối liên hệ giữa
CTDL và GT
Giải bài toán bằng máy tính:

4
1.1. Khái niệm về giải thuật, mối liên hệ giữa
CTDL và GT

5
1.1. Khái niệm về giải thuật, mối liên hệ giữa
CTDL và GT

- Giải thuật chỉ phản ánh các phép xử lý trên


máy tính điện tử, còn dữ liệu với biểu diễn các
thông tin cần thiết cho bài toán
- Giải thuật và cấu trúc dữ liệu có mối quan hệ
mật thiết với nhau.
- CTDL + giải thuật = chương trình

6
Mối quan hệ giữa cấu trúc dữ liệu và giải
thuật
North Wirth say that:
Cấu trúc dữ liệu + Giải thuật = Chương trình

- Để xây dựng giải thuật phù hợp  phải xác định nó tác động
trên các kiểu dữ liệu nào.
Ví dụ: Làm nhuyễn các hạt đậu  xay chứ không băm
- Khi chọn lựa cấu trúc dữ liệu  cần phải hiểu rõ những thao
tác (giải thuật) sẽ tác động lên nó.
Ví dụ: Điểm của sinh viên dùng số không dùng chữ
- Cấu trúc dữ liệu thay đổi  giải thuật thay đổi theo
 Cấu trúc dữ liệu (data structure)
- Dữ liệu (data): Là các đối tượng mà thuật toán sẽ sử dụng để đạt
được kết quả mong muốn. Nó cũng được dùng để biểu diễn cho
các thông tin của bài boán như: các thông tin vào, thông tin ra (kết
quả) và các các thông tin trung gian nếu cần.
- Cấu trúc dữ liệu (data structure): Là một phương thức cụ thể để
lưu trữ và tổ chức dữ liệu trong máy tính để việc xử lý sao cho
hiệu quả nhất. Nó dùng để biểu diễn cho các thông tin có cấu trúc
của bài toán. Cấu trúc dữ liệu thể hiện khía cạnh logic của dữ liệu.
Chú ý: Các dữ liệu không có cấu trúc được gọi là các dữ liệu vô
hướng hay các dữ liệu đơn giản. VD: các kiểu dữ liệu số nguyên
(integer), số thực (real), logic (boolean) là các kiểu dữ liệu đơn
giản.
Ví dụ
Một chương trình quản lý điểm thi của sinh viên cần
lưu trữ các điểm số của 3 sinh viên. Do mỗi sinh viên
có 4 điểm số ứng với 4 môn học khác nhau nên dữ
liệu có dạng bảng như sau:

Sinh viên Môn 1 Môn 2 Môn3 Môn4


SV 1 7 9 5 2
SV 2 5 0 9 4
SV 3 6 3 7 4
Ví dụ: Chương trình quản lý điểm của sinh viên
Phương án 1: Sử dụng mảng một chiều
Có tất cả 3(SV)*4(Môn) = 12 điểm số cần lưu trữ, do đó
khai báo mảng KQ như sau:

5 6 7 0 6 5 8 8 5 5 9 7

SV1 SV2 SV3

Truy xuất điểm j của sinh viên i


Bảng (dòng i, cột j)=A[(i-1)*số cột+j]
Phương án 2: Sử dụng mảng 2 chiều
Khai báo mảng 2 chiều KQ có kích thước 3
dòng* 4 cột như sau:
Cot 1 Cot 2 Cot3 Cot 4
Dang 1 a[1,1] = 7 a[1,2] = 9 a[1,3] = 7 a[1,4] = 5
Dang 2 a[2,1] = 5 a[2,2] = 4 a[2,3] = 2 a[2,4] = 7
Dang 3 a[3,1] = 8 a[3,2] = 9 a[3,3] = 6 a[3,4] = 7

Và truy xuất điểm số môn j của sinh viên i là


phần tử tại dòng i cột j trong bảng- cũng
chính là phần tử ở dòng i cột j trong mảng.
Bảngđiểm (dòng i, cột j)  a[i,j]
-> chọn phương án nào?
1.1. Khái niệm về giải thuật, mối liên hệ giữa
CTDL và GT

Có thể thấy rõ phương án 2 cung cấp một cấu


trúc lưu trữ phù hợp với dữ liệu thực tế hơn
phương án 1, và do vậy giải thuật xử lý trên cấu
trúc dữ liệu của phương án 2 cũng đơn giản, tự
nhiên hơn.

12
1.1. Khái niệm về giải thuật, mối liên hệ giữa
CTDL và GT
- Các tiêu chuẩn khi lựa chọn cấu trúc dữ liệu
+ Cấu trúc dữ liệu trước hết phải biểu diễn được đầy đủ các thông
tin nhập và xuất của bài toán (Phản ánh đúng thực tế).
+ Cấu trúc dữ liệu phải phù hợp với các thao tác của thuật toán mà
ta lựa chọn để giải quyết bài toán.
+ Cấu trúc dữ liệu phải cài đặt được trên máy tính với ngôn ngữ
lập trình đang sử dụng.
+ Tiết kiệm tài nguyên hệ thống.
Đối với một số bài toán, trước khi tổ chức dữ liệu ta phải viết một
đoạn chương trình nhỏ để khảo sát xem dữ liệu cần lưu trữ lớn tới
mức độ nào.
1.1. Khái niệm về giải thuật, mối liên hệ giữa
CTDL và GT
- Vai trò của CTDL
+ CTDL đóng vai trò quan trọng trong việc kết hợp thuật toán
(thuật giải hay giải thuật) để đưa ra cách giải quyết bài toán.
+ CTDL hỗ trợ cho các thuật toán thao tác trên đối tượng được
hiệu quả hơn.
1.1. Khái niệm về giải thuật, mối liên hệ giữa
CTDL và GT
- Các bước xây dựng một CTDL:
Bước 1: xác định đầy đủ các đặc trưng của CTDL gồm:
+ Các thành phần DL có trong CTDL đó,
+ Các liên kết (quan hệ) về cấu trúc giữa các thành phần DL.
Bước 2: xác định các thao tác cơ bản trên CTDL: là các thao tác cơ bản, cần
thiết nhất để có thể sử dụng được CTDL này.
Bước 3: xác định cấu trúc lưu trữ thích hợp để tổ chức lưu trữ CTDL một
cách có hiệu quả. Tính hiệu quả thể hiện ở cả hai mặt: kích thước lưu trữ
nhỏ nhất và tốc độ thực hiện các thao tác là nhanh nhất.
Bước 4: Cài đặt các thao tác cơ bản. Việc cài đặt các thao tác phải theo một
số nguyên tắc sau:
+ Thao tác có khả năng sử dụng lại nhiều lần: sử dụng chương trình con để
cài đặt.
+ Thao tác có tính độc lập về mặt sử dụng và độc lập với các thao tác khác.
Để đảm bảo tính chất này thì ta phải chọn các tham số hợp lí cho các thao
tác.
+ Thao tác phải hiệu quả.
1.1. Khái niệm về giải thuật, mối liên hệ giữa
CTDL và GT
- Giải thuật (thuật giải hoặc thuật toán): Là một dãy hữu
hạn các thao tác đơn giản được sắp xếp theo một trình tự xác
định sao cho sau khi thực hiện dãy thao tác đó, từ Input của
bài toán, ta nhận được Output cần tìm.
- Một số yêu cầu của giải thuật:
+ Đúng đắn.
+ Rõ ràng (không nhập nhằng).
+ Phải kết thúc sau một số hữu hạn bước thực hiện.
+ Có mô tả các đối tượng dữ liệu mà thuật toán sẽ thao tác
như dữ liệu vào (nguồn), dữ liệu ra (đích) và các dữ liệu
trung gian.
+ Thời gian thực hiện phải hợp lý.
1.1. Khái niệm về giải thuật, mối liên hệ giữa
CTDL và GT
- Các tiêu chí đánh giá giải thuật:
+ Đơn giản, dễ hiểu
+ Dễ cài đặt
+ Cần ít bộ nhớ
+ Chạy nhanh
Sự cần thiết của giải thuật
• Tại sao sử dụng máy tính để xử lý dữ liệu?
 Nhanh hơn.
 Nhiều hơn.
 Giải quyết những bài toán mà con người không thể hoàn
thành được.
• Làm sao đạt được những mục tiêu đó?
 Nhờ vào sự tiến bộ của kỹ thuật: tăng cấu hình máy  chi
phí cao 
 Nhờ vào các thuật toán hiệu quả: thông minh và chi phí thấp

“Một máy tính siêu hạng vẫn không thể cứu vãn một thuật
toán tồi!”
1.1. Khái niệm về giải thuật, mối liên hệ giữa
CTDL và GT
b. Các đặc trưng của giải thuật:
- Tính xác định: mỗi bước của thuật toán các thao tác phải hết sức rõ ràng

- Tính hữu hạn dừng: giải thuật bao giờ cũng phải dừng sau một số hữu
hạn bước

- Tính đúng đắn: sau khi thực hiện tất cả các thao tác của thuật toán ta
phải được kết quả mong muốn

- Tính phổ dụng: có thể giải bất kỳ bài toán nào trong cùng một lớp các
bài toán

19
1.1. Khái niệm về giải thuật, mối liên hệ giữa
CTDL và GT
- Tính có đại lượng vào và đại lượng ra: khi giải thuật bắt đầu bao giờ cũng
nhận các đại lượng vào (input: dữ liệu vào) và sau khi kết thúc một thuật
toán bao giờ cũng đưa ra một số đại lượng kết quả theo yêu cầu (output:
dữ liệu ra).

- Tính hiệu quả: hiệu quả của một giải thuật được đánh giá dựa trên các tiêu
chuẩn:
+ Dung lượng bộ nhớ cần có
+ Số các phép tính cần thực hiện
+ Thời gian cần thiết để chạy
+ Có dễ hiểu không
+ Có dễ cài đặt trên máy không
20
1.2. Cấu trúc dữ liệu và các vấn đề liên quan

- Các dữ liệu nguyên thuỷ


- Cấu trúc tiền định (Mảng, Xâu, bản ghi,…)
- Cấu trúc dữ liệu trừu tượng
- Cấu trúc dữ liệu logic (định nghĩa) và cấu trúc dữ
liệu vật lý (lưu trữ)

21
1.3. Ngôn ngữ diễn đạt giải thuật

 Dạng ngôn ngữ tự nhiên


 Dạng lưu đồ (sơ đồ khối)
 Dạng mã giả
 Ngôn ngữ lập trình

22
Mô tả bằng Ngôn ngữ (NN) tự nhiên
• NN tự nhiên thông qua các bước được tuần tự liệt kê để biễu
diễn thuật toán.
• Ưu điểm:
 Đơn giản, không cần kiến thức về cách biểu diễn (mã giả,
lưu đồ,...)
• Nhược điểm:
 Dài dòng, không cấu trúc.
 Đôi lúc khó hiểu, không diễn đạt được thuật toán.
Mô tả bằng Lưu đồ

A A

Thực hiện A Gọi hàm A Vào / Ra dữ liệu

Đúng
B Begin
End
Sai

Nút giới hạn bắt đầu /


Điều kiện rẽ nhánh B
kết thúc chương trình
Mô tả bằng Lưu đồ

Bắt đầu amax = a0


Tìm phần tử mang
giá trị lớn nhất
i= 1 trong mảng

S amax là lớn nhất Kết thúc


i<n

amax < ai Đ
amax =ai

S
i = i+1
Bài Tập
• Vẽ lưu đồ và viết chương trình
1. Viết chương trình nhập vào hai số nguyên dương a và b.
Tìm ước số chung lớn nhất và bộI số chung nhỏ nhất của a
và b.
2. Nhập vào ngày, tháng, năm. Kiểm tra xem ngày, tháng,
năm đó có hợp lệ hay không? In kết quả ra màn hình.
3. Viết chương trình nhập số nguyên dương n. Kiểm tra số
đó có phải số nguyên tố hay không?
4. Một số hoàn thiện là một số có tổng các ước số của nó
(không kể nó) bằng chính nó. Hãy liệt kê các số hoàn thiện
nhỏ hơn 5000.
Mô tả bằng Mã giả

• Ngôn ngữ tựa ngôn ngữ lập trình:

 Dùng cấu trúc chuẩn hóa, chẳng hạn tựa Pascal, C.

 Dùng các ký hiệu toán học, biến, hàm.

• Ưu điểm:

 Đỡ cồng kềnh hơn lưu đồ khối.

• Nhược điểm:

 Không trực quan bằng lưu đồ khối.


Mô tả bằng Mã giả
• Một số quy ước
1. Các biểu thức toán học
2. Lệnh gán: “:=” (AB)
3. So sánh: “=”, “<>”
4. Khai báo hàm (thuật toán)
Thuật toán <tên TT> (<tham số>)
BEGIN
Input: <dữ liệu vào>
Output: <dữ liệu ra>
<Các câu lệnh>
End
Mô tả bằng Mã giả

5. Các cấu trúc:


Cấu trúc chọn:
if … then … [else …]
Vòng lặp:
while … do
repeat … Until …
for … to … do …
6. Một số câu lệnh khác:
Lệnh gán: x := y
Lời gọi hàm: <Tên>(tham số)
Mô tả bằng Mã giả
Ví dụ: Tìm phần tử lớn nhất trong mảng một chiều.

amax :=a0;

i :=1;
while (i<n) do
Begin
if (amax< ai) then amax := ai;

i := i+1;

End;
Mô tả bằng Ngôn ngữ lập trình

• Dùng ngôn ngữ máy tính (C, Pascal,...) để diễn tả


thuật toán, CTDL thành câu lệnh.

• Kỹ năng lập trình đòi hỏi cần học tập và thực hành
(nhiều).

• Dùng phương pháp tinh chế từng bước để chuyển hoá


bài toán sang mã chương trình cụ thể.
1.4. Thiết kế giải thuật

• Từ bài toán đến chương trình

Thiết kế Lập trình #include


Bài toán …
thực tế

Giải thuật Chương trình

Kỹ thuật thiết kế giải •Ngôn ngữ lập


thuật: trình:
Chia để trị, quy hoạch •PASCAL, C/C++,
động, JAVA, C#
backtracking ..vv
1.4. Thiết kế giải thuật

• Với một vấn đề đặt ra, làm thế nào để đưa ra thuật toán
giải quyết nó?
• Chiến lược thiết kế:
• Chia-để-trị (divide-and-conquer)
• Quy hoạch động (dynamic programming)
• Quay lui (backtracking)
• Tham lam (greedy method)
1.4. Thiết kế giải thuật

• Module hoá và việc giải quyết bài toán


• Chiến thuật chia để trị (divide-conquer):
• Để thực hiện chiến thuật này, thường có hai cách thiết
kế:
1.Từ trên xuống (Top-Down Design).
2.Tinh chỉnh từng bước
1.4. Thiết kế giải thuật

• Sau đây là lược đồ của kỹ thuật chia-để-trị:

DivideConquer (A,x) // tìm nghiệm x của bài toán A.



if (A đủ nhỏ)
Solve (A);
else 
Chia bài toán A thành các bài toán con
A1, A2,…, Am;
for (i = 1; i <= m ; i ++)
DivideConquer (Ai , xi);
Kết hợp các nghiệm xi của các bài toán con Ai (i=1, …, m)
để nhận được nghiệm x của bài toán A;


1.4. Thiết kế giải thuật

• Tinh chỉnh từng bước:


• Biểu diễn ý tưởng bằng ngôn ngữ tự nhiên
• Cụ thể từng phần, thay đổi bằng ngôn ngữ
chương trình
• Cuối cùng ta có chương trình
1.4. Thiết kế giải thuật

• Ví dụ: Bài toán sắp xếp một dãy n số, theo thư tự tăng dần
• Chọn số bé nhất trong n số để vào vị trí thứ 1
• Chọn số bé nhất trong n-1 số còn lại để vào vị trí thứ 2
• …………………
• Chọn số bé nhất trong 2 số còn lại để vào vị trí thứ n-1
1.4. Thiết kế giải thuật

•  For (i= 1, i <= n-1, i++)


{- Chọn số bé nhất trong các số
- Đổi chỗ cho xi
}
•  For (i= 1, i <= n-1, i++)
{- tg = x[i]
-So sánh tg với các số từ xi+1 -> xn . Nếu x[i] > các số đó thì
lại lấy số đó làm số tg
- đổi chổ x[i] và tg
}
1.4. Thiết kế giải thuật

for (i= 1; i <= n-1; i++)


for(j = i+1; j <=n; j++) {
If (x[j] < x[i])
{
Tg = x[i] ;
X[i] = x[j];
X[j] := tg ;
}
}
Thiết kế giải thuật (tt)

• Ví dụ 3: Tìm tất cả các số tự nhiên có hai chữ số, khi đảo


trật tự của hai số đó sẽ tạo được một số nguyên tố cùng
nhau với số đã cho
• Phân tích giả thiết
• Gọi x=ab là số có hai chữ số cần tìm
• a,b = 0…9
• a>0
• (ab,ba)=1
Thiết kế giải thuật (tt)

• Ví dụ 3 (tt)
• Tinh chỉnh 1
• x = 10…99
• x’ = 10*donvi(x)+chuc(x)
• (x,x’)=1  USCLN(x,x’)=1
• Tinh chỉnh 2
• x chạy từ 10 đến 99
• y=10*donvi(x)+chuc(x)
• nếu USCLN(x,y)=1 thì Xuất(x)
Thiết kế giải thuật (tt)

• Khi một giải thuật được xây dựng, hàng loạt yêu cầu đặt
ra
• Yêu cầu về tính đúng đắn của giải thuật
• Tính đơn giản của giải thuật.
• Yêu cầu về không gian :
• Yêu cầu về thời gian :
Thiết kế giải thuật (tt)

• Giải quyết bài toán


• Phải đứng trước việc lựa chọn giải thuật nào ?
• Dựa trên cơ sở nào để lựa chọn ?
• Có hai mục tiêu trái ngược
• Thuật toán dễ hiểu, cài đặt và gỡ lỗi (1).
• Thuật toán sử dụng hiệu quả tài nguyên máy tính, đặc
biệt chạy càng nhanh càng tốt (2).
Thiết kế giải thuật (tt)

• Độ phức tạp không gian (Space complexity)


• Dung lượng bộ nhớ mà thuật toán đòi hỏi
• Độ phức tạp thời gian (Time complexity)
• Thời gian thực hiện thuật toán
1.5. Phân tích độ phức tạp của giải thuật

• Thời gian thực hiện giải thuật phụ thuộc vào các
yếu tố sau:
• Dữ liệu vào
• Tốc độ thực hiện các phép toán của máy
tính (phần cứng máy tính)
• Trình biên dịch
1.5. Phân tích độ phức tạp của giải thuật

• Sử dụng các công cụ toán học để đánh giá thời


gian chạy của giải thuật:
• Gọi n là kích thước của dữ liệu vào, thời gian
thực hiện của giải thuật có thể biểu diễn là một
như hàm của n: hàm T(n)
1.5. Phân tích độ phức tạp của giải thuật

• Bước 1: Phân tích kích thước dữ liệu vào


• Bước 2: Phân tích (toán học) tìm ra giá trị trung bình,
và giá trị xấu nhất cho mỗi đại lượng cơ bản.
• Ví dụ 4:
• Giải thuật A, độ phức tạp thời gian Ta(n)
• Giải thuật B, độ phức tạp thời gian Tb(n)
• Khi n lớn, Ta(n) >> Tb(n). Có thể kết luận giải thuật A
chậm hơn giải thuật B.
Ký pháp để đánh giá độ phức tạp tính
toán của giải thuật

• Ký hiệu O (big-Oh): hàm f(n) và g(n), ta nói:


f(n) = Ο(g(n)), nếu tồn tại các hằng số dương c và no
sao cho f(n) ≤ cg(n) khi n ≥ no.
• Ký hiệu này dùng để chỉ chặn trên của một hàm
• Ý nghĩa: Tốc độ tăng của hàm f(n) không lớn hơn hàm
g(n)
Ký pháp để đánh giá độ phức tạp tính
toán của giải thuật

f(n) = 2n + 6
• Ví dụ : c g(n) = 4n
f(n) = 2n+6,
g(n) = n và c = 4 , n0=3
• f(n)= O(n)

g(n) = n

N0 = 3
n
Ký pháp để đánh giá độ phức tạp tính
toán của giải thuật
• Định nghĩa Ω:
- f(n) = Ω(g(n)), nếu tồn tại các hằng số dương c và no
sao cho f(n) ≥ cg(n) khi n ≥ no
- f(n) = Ω(g(n))  g(n) = Ο(f(n))
• Định nghĩa 
f(n) = (g(n)), nếu tồn tại các hằng số dương c1, c2 và n0
sao cho c1.g(n)  f(n)  c2. g(n) với mọi n> n0
Ký pháp để đánh giá độ phức tạp tính
toán của giải thuật

f ( n ) O ( g ( n )) f ( n )   ( g ( n ))

cg(n) f(n)

f(n)
cg(n)

n0 n0
Ký pháp để đánh giá độ phức tạp tính
toán của giải thuật

f ( n )   ( g ( n ))
c2g(n)
f(n)

c1g(n)

n0
Ký pháp để đánh giá độ phức tạp tính
toán của giải thuật

• Ta nói độ phức tạp tính toán của giải thuật có cấp f(n)
nếu thỏa :
• T(n) = O(f(n)), và
• Nếu  g(n), mà T(n) = O(g(n)) thì f(n) = O(g(n)).
Một số qui tắc về ký hiệu O lớn

• Nếu f1(n)=O(g1(n)) và f2(n)=O(g2(n))


• f1(n)+f2(n)=O(g1(n)+g2(n))=max(O(g1(n),g2(n))
• f1(n)*f2(n)=O(g1(n)*g2(n))
• logkN=O(N) với mọi hằng số k
• Nếu f(n) là một đa thức bậc k,
• thì f(n) là O(nk),
Một số qui tắc về ký hiệu O lớn

• f = O(f)
• f = O(g) và g = O(h) thì f = O(h)
• f = O(g) và h=O(r) thì fh = O(gr)
• f =O(g) và h=O(r) thì f+h = O(g+r)
• f =O(g) thì af = O(g) với mọi a>0.
• O(c)=O(1) , c là hằng số
Một số qui tắc về ký hiệu O lớn

• Ví dụ:
• 2n là O(n)
• 3n + 5 là O(n) thay vì 3n + 5 là O(3n)
• 4n2 + 5n + 7 la O(?)
Xác định độ phức tạp tính toán

• T1(n) và T2(n) là thời gian thực hiện của hai giai đoạn chương
trình P1 và P2 mà T1(n) = O(f(n)); T2(n) = O(g(n))
• Qui tắc tổng:
• Thời gian thực hiện đoạn P1 rồi P2 tiếp theo sẽ là T1(n) + T2(n)
= O(max(f(n),g(n))).
• Qui tắc nhân:
• Thời gian thực hiện P1 và P2 lồng nhau sẽ là : T1(n)T2(n) =
O(f(n)*g(n))
Các qui tắc tổng quát

• Các phép gán, đọc, viết, goto là các phép toán sơ


cấp:
• Thời gian thực hiện là: O(1)
• Lệnh lựa chọn: if-else có dạng
if (<điều kiện>)
lệnh 1
else
lệnh 2
Các qui tắc tổng quát

• Câu lệnh switch được đánh giá tương tự như lệnh if-
else.
• Các lệnh lặp: for, while, do-while
• Cần đánh giá số tối đa các lần lặp, giả sử đó là L(n)
• Tiếp theo đánh giá thời gian chạy của mỗi lần lặp là
Ti(n), (i=1,2,..., L(n))
• Mỗi lần lặp, chi phí kiểm tra điều kiện lặp,là T0(n).
• Chí phí lệnh lặp là:
L(n)

 T n   T n 
i 1
0 i
Một số ví dụ
• Ví dụ 1. Mảng A các số thực, cỡ n, cần tìm xem mảng có
chứa số thực x không.
(1) i = 0;
(2) while (i < n && x != A[i])
(3) i++;
Một số ví dụ

Case1: for (i=0; i<n; i++)


for (j=0; j<n; j++)
k++;
O(n2)

Case 2: for (i=0; i<n; i++)


k++; O(n2)
for (i=0; i<n; i++)
for (j=0; j<n; j++)
k++;

Case 3: for (int i=0; i<n-1; i++) O(n2)


for (int j=0; j<i; j++)
int k+=1;
Một số ví dụ

int MaxSubSum1(const int a[], int n) {


int maxSum=0;

for (int i=0; i<n; i++)


for (int j=i; j<n; j++) {
int thisSum=0; O(n )
3

for (int k=i; k<=j; k++)


thisSum+=a[k];

if (thisSum>maxSum)
maxSum=thisSum;
}
return maxSum;
Một số ví dụ
int MaxSubSum2(const int a[], int n) {
int maxSum=0;

for (int i=0; i<n; i++) {


thisSum=0;
for (int j=i; j<n; j++) {
thisSum+=a[j]; O(n )
2

if (thisSum>maxSum)
maxSum=thisSum;
}
}
return maxSum;
}
Một số ví dụ

int MaxSubSum4(const int a[], int n) {


int maxSum=0, thisSum=0;

for (int j=0; j<n; j++) {


thisSum+=a[j];

if (thisSum>maxSum)
maxSum=thisSum;
O(n)
else if (thisSum<0)
thisSum=0;
}
return maxSum;
}
Một số ví dụ

Sum=0
for (j=0;j<N;j++)
for (k=0;k<N*N;k++)
Sum++; O(N
O(N ))
33
Một số ví dụ

Ví dụ: sắp xếp dãy


void BubbleSort(int a[], int n)
{ int i,j,temp;
(1) for(i= 0; i<=n-2; i++)
(2) for(j=n-1; j>=i+1;j--)
(3) if (a[j] < a[j-1]) {
(4) temp=a[j-1];
(5) a[j-1] = a[j];
(6) a[j] = temp;
}
}
Một số ví dụ

• Lệnh (3), (4), (5) và (6) đều tốn O(1)


• Vòng lặp (2) thực hiện (n-i) lần, mỗi lần O(1) do đó vòng lặp (2)
tốn O((n-i)*1) = O(n-i).
• Vòng lặp {1},i chạy từ 1 đến n-1, thời gian thực hiện của vòng
lặp (1)
• Độ phức tạp của giải thuật là
PHÂN TÍCH CÁC HÀM ĐỆ QUY

• Ví dụ: Hàm tính giai thừa


int Fact(int n)
{
if (n <= 1)
return 1;
else return n * Fact(n-1);
}
• Với n <= 1, ta có T(1) = O(1).
• Với n > 1, ta có T(n) = 0(1) + T(n-1)
PHÂN TÍCH CÁC HÀM ĐỆ QUY

• Ta có quan hệ đệ quy sau:


• T(1) = O(1)
• T(n) = T(n-1) + O(1) với n > 1
• Thay các ký hiệu O(1) bởi các hằng số dương a và b tương
ứng, ta có
• T(1) = a
• T(n) = T(n-1) + b với n > 1
PHÂN TÍCH CÁC HÀM ĐỆ
QUY

• Sử dụng các phép thế T(n-1) = T(n-2) + b, T(n-2) =


T(n-3) + b,..., ta có
T(n) = T(n-1) + b
= T(n-2) + 2b
= T(n-3) + 3b
...
= T(1) + (n-1)b
= a + (n-1)b
Từ đó, ta suy ra T(n) = O(n).
PHÂN TÍCH CÁC HÀM ĐỆ
QUY
• Gọi T(n) là thời gian chạy của hàm đệ quy F
• Khi đó, thời gian chạy của các lời gọi hàm ở trong hàm F
sẽ là T(m) (với m < n)
• Trước hết, phải đánh giá thời gian chạy của hàm F trên dữ
liệu nhỏ nhất n = 1, giả sử T(1) = a (điều kiện dừng)
• Sau đó, đánh giá thời gian chạy của các câu lệnh trong
thân của hàm F
• Tìm ra quan hệ đệ quy biểu diễn thời gian chạy của hàm F
thông qua lời gọi hàm
Sự phân lớp của giải thuật

 Độ phức tạp
 O(1) độ phức tạp hằng số
 O(logn) độ phức tạp logarit
 O(n) độ phức tạp tuyến tính
 O(nlogn) độ phức tạp nlogn
 O(nb) độ phức tạp đa thức
 O(bn) độ phức tạp mũ
 O(n!) độ phức tạp giai thừa
Sự phân lớp của giải thuật
Đánh giá độ phức tạp trong ba
trường hợp

• Độ phức tạp tính toán của giải thuật trong các trường
hợp
• Xấu nhất
• Tốt nhất
• Trung bình
Đánh giá độ phức tạp trong ba trường hợp

• Ví dụ 8: Thuật toán tìm kiếm tuần tự

int sequenceSearch(int x, int a[], int n){


for (int i=0;i<n;i++){
if (x==a[i]) return i;
}
return -1;
}
Đánh giá độ phức tạp trong ba trường
hợp
• Tốt nhất: phần tử đầu tiên là phần tử cần tìm, số
lượng phép so sánh là 2  T(n) ~ O(2) = O(1)
• Xấu nhất: so sánh đến phần tử cuối cùng, số lượng
phép so sánh là 2n  T(n) ~ O(n)
• Trung bình: so sánh đến phần tử thứ i, cần 2i phép so
sánh, vậy trung bình cần
(2+4+6+…+2n)/n=2(1+2+…+n)/n=n+1
 T(n) ~ O(n)
Kiến thức Toán học bổ trợ
về Tổng các chuỗi

N
S ( N )  1  2    N   i  N (1  N ) / 2
i 1

• Tổng các BP:


N
N ( N  1)( 2 N  1) N 3

i 1
i 
2

6

3
for large N

• Logarithms:
• xa = b  logx b = a
Kiến thức Toán học bổ trợ về Tổng các chuỗi

N
N k 1

i 1
k
i 
| k 1|
for large N and k  -1

N
A N 1  1

i 0
A 
i

A 1
• Đặc biệt khi A = 2
• 20 + 21 + 22 + … + 2N = 2N+1 - 1
Q&A
III - TỔNG KẾT

- Khái niệm về giải thuật, cấu trúc dữ liệu, vai trò


của giải thuật, mối quan hệ giữa CTDL và GT
- Ngôn ngữ diễn tả giải thuật.
- Phương pháp xây dựng giải thuật
- Độ phức tạp của thuật toán
- Đệ qui và các giải thuật đệ qui đơn giản

Slide 81
IV - CHUẨN BỊ CHO BÀI HỌC SAU

- Làm bài tập chương 1 giáo viên giao

- Nghiên cứu tài liệu và chuẩn bị trước Bài 2:


Danh sách tuyến tính

Slide 82

You might also like