Tải bản đầy đủ (.pdf) (74 trang)

BÀI GIẢNG PHÂN TÍCH THIẾT KẾ VÀ ĐÁNH GIÁ THUẬT TOÁN. TRÌNH ĐỘ ĐÀO TẠO : ĐẠI HỌC CHÍNH QUY DÙNG CHO SV NGÀNH : CÔNG NGHỆ THÔNG TIN

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (936.83 KB, 74 trang )

BỘ GIAO THÔNG VẬN TẢI
TRƢỜNG ĐẠI HỌC HÀNG HẢI
BỘ MÔN: KHOA HỌC MÁ Y TÍ NH
KHOA: CÔNG NGHỆ THÔNG TIN

BÀI GIẢNG
PHÂN TÍCH THIẾT KẾ VÀ ĐÁNH GIÁ
THUẬT TOÁN
TÊN HỌC PHẦN : Phân tích thiết kế và đánh giá thuật toán
MÃ HỌC PHẦN : 17208
TRÌNH ĐỘ ĐÀO TẠO : ĐẠI HỌC CHÍNH QUY
DÙNG CHO SV NGÀNH : CÔNG NGHỆ THÔNG TIN

HẢI PHÕNG - 2010


Tên học phần: Phân tić h thiế t kế và đánh giá thuâ ̣t toán
Bộ môn phụ trách giảng dạy: Khoa học Máy tính
Mã học phần: 17208
TS tiết
60

Lý thuyết
45

Thực hành/Xemina
15

Tự học
0


Loại học phần: 2
Khoa phụ trách: CNTT
Tổng số TC: 3

Bài tập lớn
0

Đồ án môn học
0

Điều kiện tiên quyết:
Sinh viên phải học xong các học phần sau mới đƣợc đăng ký học phần này:
Kỹ thuật lập trình, Cấ u trúc dƣ̃ liê ̣u, Toán rời rạc
Mục tiêu của học phần:
Cung cấp các kiến thức cơ bản về thuật toán, cấu trúc dữ liệu.
Cung cấ p các kiế n thƣ́c về chiế n lƣơ ̣c xây dƣ̣ng và đánh giá thuâ ̣t toán
Rèn luyện tƣ duy khoa học.
Nội dung chủ yếu
Gồm 4 phần:
Các kiến thức cơ bản về thuật toán.
Các kiến thức cơ bản về sắp xếp và tìm kiếm dữ liệu.
Các chiến lƣợc thiế t kế thuâ ̣t toán : chiến lƣợc chia để trị, chiến lƣợc quay lui,
chiến lƣợc qui hoạch động, chiến lƣợc tham lam
Kiế n thƣ́c cơ bản về đánh giá đô ̣ phƣ́c ta ̣p thuâ ̣t toán .
Nội dung chi tiết của học phần:
TÊN CHƢƠNG MỤC
Chƣơng I. Các khái niệm cơ bản
1.1. Giới thiệu về thuật toán
1.1.1 Khái niệm về thuật toán.
1.1.2. Các phƣơng pháp biểu diễn thuật toán

1.1.3. Các ví dụ biểu diễn thuật toán sơ đồ khối
1.2. Độ phức tạp thuật toán
1.2.1. Các ký hiệu , hàm đánh giá độ phức tạp
thuâ ̣t toán
1.2.2. Các lớp thuật toán
1.3. Mố i quan hê ̣ giƣ̃a cấ u trúc dƣ̃ liê ̣u và giải
thuâ ̣t
1.4. Mô ̣t số ví du ̣
Chƣơng II. Sắ p xế p và tim
̀ kiế m
2.1. Bài toán sắp xếp
2.1.1. Sắ p xế p trong
2.1.2. Sắ p xế p ngoài
2.1.3. Đánh giá thuâ ̣t toán sắ p xế p
2.2. Các thuật toán sắp xếp cơ bản
2.2.1. Sắ p xế p cho ̣n (Selection Sort)
2.2.2. Sắ p xế p đổ i chỗ trƣ̣c tiế p (Exchange Sort)
2.2.3. Sắ p xế p chèn (Insertion Sort)
2.2.4. Sắ p xế p nổ i bo ̣t (Bubble Sort)
2.2.5. So sánh các thuâ ̣t toán sắ p xế p cơ bản

PHÂN PHỐI SỐ TIẾT
TS LT TH/Xemina
5
4
0
1

2


BT
1

KT
0

1

0,5
0,5

15

7
0,5

5

2

3

2,5

1

1

i



TÊN CHƢƠNG MỤC
2.3. Sắ p xế p vun đố ng
2.3.1. Cấ u trúc Heap
2.3.2. Thuâ ̣t toán xây dƣ̣ng cấ u trúc Heap
2.3.3. Thuâ ̣t toán sắ p xế p vun đố ng
2.4. Tìm kiếm tuyến tính
2.4.1. Bài toán tìm kiếm
2.4.2. Thuâ ̣t toán tim
̀ kiế m tuyế n tiń h
Chƣơng III. Đê ̣qui và chiế n lƣơ ̣c vét ca ̣n
3.1. Khái niệm về đệ quy
3.1.1. Giải thuật đệ quy và thủ tục đệ quy
3.1.2. Thiết kế giải thuật đệ quy
3.1.3. Hiệu lực của đệ quy.
3.1.4. Đệ quy và quy nạp toán học.
3.2. Chiế n lƣơ ̣c vét ca ̣n (Bruteforce)
3.3. Chiế n lƣơ ̣c đê ̣ qui quay lui (backtracking)
3.3.1. Vector nghiê ̣m
3.3.2. Thủ tục đệ qui
3.3.3. Các giá trị đề cử
3.3.4. Điề u kiê ̣n chấ p nhâ ̣n
3.3.5. Mô ̣t số bài toán backtracking điể n hiǹ h
Chƣơng IV. Chiế n lƣơ ̣c chia để tri ̣
4.1. Cơ sở của chiế n lƣơ ̣c chia để tri ̣
4.2. Thuâ ̣t toán sắ p xế p bằ ng trô ̣n
4.2.1. Thuâ ̣t toán trô ̣n hai Run
4.2.2. Sắ p xế p bằ ng trô ̣n
4.3. Sắ p xế p nhanh (Quick sort)
4.3.1. Chiế n lƣơ ̣c phân hoa ̣ch

4.3.2. Quick sort
4.4. Tìm kiếm nhị phân
4.5. Thuâ ̣t toán nhân số nguyên
4.5.1. Thuâ ̣t toán nhân tay
4.5.2. Thuâ ̣t toán chia để tri ̣
4.6. Mô ̣t số bài toán khác
Chƣơng V. Qui hoa ̣ch đô ̣ng
5.1. Chiế n lƣơ ̣c qui hoa ̣ch đô ̣ng
5.1.1. Các điều kiện để áp dụng
5.1.2. Các bƣớc trong qui hoạch động
5.1.3. Các kiểu qui hoạch động
5.2. Bài toán dãy số Fibonaci
5.2.1. Thuâ ̣t toán đê ̣ qui
5.2.2. Thuâ ̣t toán qui hoa ̣ch đô ̣ng
5.3. Bài toán dãy con chung dài nhất
5.4. Bài toán nhân ma trận
5.5. Mô ̣t số ví du ̣ khác
Chƣơng VI. Chiế n lƣơ ̣c tham lam
6.1. Nguyên tắ c tham lam
6.2. Bài toán đổi tiền
6.3. Bài toán sắp lịch các sự kiện
6.3.1. Thuâ ̣t toán đê ̣ qui

PHÂN PHỐI SỐ TIẾT
TS LT TH/Xemina
2,5 1,5

11

11


12

6

1

1

6
1

3

0,5

1
2

1
1
1
0,5
1
6
0,5
1,5

3


BT
1

KT

2
1

0

1
1

1

1
2

1

1

1,5

1

1
1

1


0,5
6
1,5

3

1

0,5

1
1,5
1
4
0,5
1
2

1
1
0,5
1

1
1
1

0


1

ii


TÊN CHƢƠNG MỤC
6.3.2. Thuâ ̣t toán theo chiế n lƣơ ̣c tham lam
6.4. So sánh chiế n lƣơ ̣c tham lam với chiế n lƣơ ̣c
qui hoa ̣ch đô ̣ng

PHÂN PHỐI SỐ TIẾT
TS LT TH/Xemina
0,5

BT

KT

1

Nhiệm vụ của sinh viên :
Tham dự các buổi thuyết trình của giáo viên, tự học, tự làm bài tập do giáo viên giao,
tham dự các bài kiểm tra định kỳ và cuối kỳ.
Tài liệu học tập :
Nguyễn Hữu Điển, Giáo trình một số vấn đề về thuật toán, NXB Giáo dục,
2003
Đinh Mạnh Tƣờng. Cấu trúc dữ liệu và thuật toán. NXB Đại học Quốc gia Hà
nội. 2002.
Nguyễn Quốc Lƣợng, Hoàng Đức Hải. Cấu trúc dữ liệu + giải thuật = chương
trình. NXB Giáo dục. 1996

Richard Neapolitan và Kumarss Naimipour, Foundations of Algorithms Using
C++ Pseudocode, Third Edition, Jones and Bartlett Publishers, 2004.
Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein,
Introduction to Algorithms, Second Edition, MIT Press, 2001.
Hình thức và tiêu chuẩn đánh giá sinh viên:
Hình thức thi cuối kỳ : Thi vấn đáp.
Sinh viên phải đảm bảo các điều kiện theo Quy chế của Nhà trƣờng và của Bộ
Thang điểm: Thang điểm chữ A, B, C, D, F
Điểm đánh giá học phần: Z = 0,3X + 0,7Y.
Bài giảng này là tài liệu chính thức và thống nhất của Bộ môn Khoa học Máy tính,
Khoa Công nghệ Thông tin và đƣợc dùng để giảng dạy cho sinh viên.
Ngày phê duyệt:

/

/20

Trƣởng Bộ môn: ThS. Nguyễn Hữu Tuân (ký và ghi rõ họ tên)

iii


Bài giảng môn học: Phân tích thiế t kế và đánh giá giải thuật
MỤC LỤC
LỜI NÓI ĐẦU ............................................................................................................................ 1
CHƢƠNG I: CÁC KHÁI NIỆM CƠ BẢN ................................................................................ 2
1. Thuâ ̣t toán (giải thuật) - Algorithm ............................................................................... 2
1.1. Đinh
̣ nghiã thuâ ̣t toán ............................................................................................. 2
1.2. Đặc trƣng của thuật toán ........................................................................................ 2

2. Biể u diễn thuâ ̣t toán ...................................................................................................... 2
2.1. Mô tả các bƣớc thực hiện....................................................................................... 2
2.2. Sử dụng sơ đồ (lƣu đồ) giải thuật (flowchart) ....................................................... 3
3. Độ phức tạp thuật toán – Algorithm Complexity.......................................................... 4
3.1. Các tiêu chí đánh giá thuật toán ............................................................................. 4
3.2. Đánh giá thời gian thƣ̣c hiê ̣n thuâ ̣t toán ................................................................. 4
3.3. Các định nghĩa hình thức về độ phức tạp thuật toán ............................................. 5
3.4. Các lớp thuật toán .................................................................................................. 7
4. Cấ u trúc dƣ̃ liê ̣u – Data structure .................................................................................. 9
5. Các chiến lƣợc thiết kế thuật toán. ................................................................................ 9
5.1. Duyệt toàn bộ (Exhausted search) ......................................................................... 9
5.2. Đệ qui quay lui – Backtracking ............................................................................. 9
5.3. Chia để tri ̣(Divide and Conquer) .......................................................................... 9
5.4. Chiế n lƣơ ̣c tham lam (Greedy) ............................................................................ 10
5.5. Qui hoa ̣ch đô ̣ng (Dynamic Programming) .......................................................... 11
6. Bài tập ......................................................................................................................... 11
CHƢƠNG II: SẮP XẾP (SORTING) VÀ TÌM KIẾM (SEARCHING) .................................. 13
1. Bài toán sắp xếp .......................................................................................................... 13
1.1. Sắ p xế p trong (Internal Sorting) .......................................................................... 13
1.2. Sắ p xế p ngoài (External Sorting) ......................................................................... 13
1.3. Sắ p xế p gián tiếp .................................................................................................. 13
1.3. Các tiêu chuẩn đánh giá một thuật toán sắp xếp .................................................. 14
2. Các phƣơng pháp sắp xếp cơ bản ................................................................................ 15
2.1. Sắ p xế p cho ̣n (Selection sort) .............................................................................. 15
2.2. Sắ p xế p đổ i chỗ trƣ̣c tiế p (Exchange sort) ........................................................... 17
2.3. Sắ p xế p chèn (Insertion sort) ............................................................................... 19
2.4. Sắ p xế p nổ i bo ̣t (Bubble sort) .............................................................................. 21

iv



Bài giảng môn học: Phân tích thiế t kế và đánh giá giải thuật
2.5. So sánh các thuật toán sắp xếp cơ bản ................................................................. 23
3. Cấ u trúc dƣ̃ liê ̣u Heap, sắ p xế p vun đố ng (Heap sort). ............................................... 24
4. Tìm kiếm tuyến tính .................................................................................................... 31
5. Các vấn đề khác .......................................................................................................... 33
6. Bài tập ......................................................................................................................... 33
CHƢƠNG III: ĐỆ QUI VÀ CHIẾN LƢỢC VÉT CẠN .......................................................... 34
1.

Khái niệm đệ qui ..................................................................................................... 34

2.

Chiế n lƣơ ̣c vét ca ̣n (Brute force) ............................................................................. 34

3.

Chiế n lƣơ ̣c quay lui (Back tracking / try and error) ................................................ 35

CHƢƠNG IV: CHIẾN LƢỢC CHIA ĐỂ TRỊ ......................................................................... 38
1.

Cơ sở của chiến lƣợc chia để tri ̣(Divide and Conquer) .......................................... 38

2.

Sắ p xế p trô ̣n (Merge sort)........................................................................................ 38

3.


Sắ p xế p nhanh (Quick sort) ..................................................................................... 43

4.

Tìm kiếm nhị phân .................................................................................................. 46

5.

Bài tập ..................................................................................................................... 48

CHƢƠNG V: QUI HOẠCH ĐỘNG ........................................................................................ 49
1.

Chiến lƣợc qui hoa ̣ch đô ̣ng ..................................................................................... 49

2.

Bài toán 1: Dãy Fibonaci ......................................................................................... 49

3.

Bài toán 2: Bài toán nhân dãy các ma trận .............................................................. 51

4.

Phƣơng pháp qui hoa ̣ch đô ̣ng .................................................................................. 53

5.


Bài toán dãy con chung dài nhất ............................................................................. 53

6.

Bài tập ..................................................................................................................... 57

CHƢƠNG VI: CHIẾN LƢỢC THAM LAM (GREEDY) ....................................................... 60
1.

Nguyên tắc tham lam............................................................................................... 60

2.

Bài toán đổi tiền ...................................................................................................... 60

3.

Bài toán lập lịch....................................................................................................... 61

4.

So sánh chiến lƣợc tham lam và qui hoạch động .................................................... 64

TÀI LIỆU THAM KHẢO ........................................................................................................ 65
ĐỀ THI THAM KHẢO ............................................................................................................ 66

v


Bài giảng môn học: Phân tích thiế t kế và đánh giá giải thuật

LỜI NÓI ĐẦU
Cấ u trúc dƣ̃ liê ̣u và các chiến lƣợc thiết kế thuật toán là các lĩnh vực nghiên cứu gắn liền
với nhau và là mô ̣t trong nhƣ̃ng liñ h vƣ̣c nghiên cƣ́u lâu đời của khoa ho ̣c máy tính . Hầ u hế t
các chƣơng trình đƣợc viết ra , chạy trên máy tính , dù lớn hay nhỏ , dù đơn giản hay phức tạp ,
đều phải sử dụng các cấu trúc dữ liệu tuân theo các trình tự , cách thức làm việc nào đó , chính
là các giải thuật . Viê ̣c hiể u biế t về các thuâ ̣t toán và các chiên lƣợc xây dựng thuật toán cho
phép các lập trình viên , các nhà khoa ho ̣c máy tiń h có nề n tảng lý thuyế t vƣ̃ng chắ c , có nhiều
lƣ̣a cho ̣n hơn trong viê ̣c đƣa ra các giải pháp cho các bài toán thƣ̣c tế
. Vì vậy việc học tập
môn ho ̣c Phân tích thiế t kế và dánh giá giải thuâ ̣t là một điề u quan tro ̣ng.
Tài liệu này dựa trên những kinh nghiệm và nghiên cứu mà tác giả đã đúc rút , thu thập
trong quá trình giảng dạy môn học Cấ u trúc dƣ̃ liê ̣u và giải thuâ ̣t tại khoa Công nghệ Thông
tin, Đại học Hàng hải Việt nam , cùng với sự tham khả o của các tài liê ̣u của các đồ ng nghiê ̣p ,
các tác giả trong và ngoài nƣớc , tƣ̀ điể n trƣ̣c tuyế n Wikipedia . Với bẩ y chƣơng đƣợc chia
thành các chủ đề khác nhau từ các khái niê ̣m cơ bản cho tới thuâ ̣t toán sắ p xế p , tìm kiếm, các
chiế n lƣơ ̣c thiế t kế thuâ ̣t toán nhƣ đê ̣ qui , quay lui , qui hoa ̣ch đô ̣ng , tham lam … hy vọng sẽ
cung cấp cho các em sinh viên , các bạn độc giả một tài liệu bổ ích . Mặc dù đã rất cố gắng
song vẫn không tránh khỏi một số thiếu sót, hy vọng sẽ đƣợc các bạn bè đồng nghiệp, các em
sinh viên, các bạn độc giả góp ý chân thành để tôi có thể hoàn thiện hơn nữa tài liệu này .
Xin gửi lời cảm ơn chân thành tới các bạn bè đồng nghiệp và Ban chủ nhiệm khoa
Công nghệ Thông tin đã tạo điều kiện giúp đỡ để tài liệu này có thể hoàn thành.
Hải phòng, tháng 04 năm 2010
Tác giả

Nguyễn Hƣ̃u Tuân

1


Bài giảng môn học: Phân tích thiế t kế và đánh giá giải thuật

CHƢƠNG I: CÁC KHÁI NIỆM CƠ BẢN
1. Thuâ ̣t toán (giải thuật) - Algorithm
1.1. Đinh
̣ nghiã thuâ ̣t toán
Có rất nhiều các định nghĩa cũng nhƣ cách phát biểu khác nhau về định nghĩa của thuật
toán. Theo nhƣ cuố n sách giáo khoa nổ i tiế ng viế t về thuâ ̣t toán
là “Introduction to
Algorithms” (Second Edition của Thomas H . Cormen, Charles E . Leiserson, Ronald L .
Rivest và Clifford Stein ) thì thuật toán đƣợc định nghĩa nhƣ sau : “mô ̣t thuâ ̣t toán là mô ̣t thủ
tục tính toán xác định (well-defined) nhâ ̣n các giá tri ̣hoă ̣c mô ̣t tâ ̣ p các giá tri ̣go ̣i là input và
sinh ra ra mô ̣t vài giá tri ̣hoă ̣c mô ̣t tâ ̣p giá tri ̣đƣơ ̣c go ̣i là output”.
Nói một cách khác các thuật toán giống nhƣ là các cách thức , qui triǹ h để hoàn thành
mô ̣t công viê ̣c cu ̣ thể xác đinh
(well-defined) nào đó. Vì thế một đoạn mã chƣơng trình tính
̣
các phần tử của dãy số Fibonaci là một cài đặt của một thuật toán cụ thể . Thâ ̣m chí mô ̣t hàm
đơn giản để cô ̣ng hai số cũng là mô ̣t thuâ ̣t toán hoàn chỉnh , mă ̣c dù đó là một thuật toán đơn
giản.
1.2. Đặc trƣng của thuật toán
Tính đúng đắn : Thuâ ̣t toán cầ n phải đảm bảo cho mô ̣t kế t quả đúng sau khi thƣ̣c hiê ̣n
đố i với các bô ̣ dƣ̃ liê ̣u đầ u vào . Đây có thể nói là đă ̣c trƣng quan tro ̣ng nhấ t đố i với mô ̣t thuâ ̣t
toán.
Tính dừng: thuâ ̣t toán cầ n phải đảm bảo sẽ dƣ̀ng sau mô ̣t số hƣ̃u ha ̣n bƣớc.
Tính xác định : Các bƣớc của thuật toán phải đƣợc phát biểu rõ ràng , cụ thể, tránh gây
nhâ ̣p nhằ ng hoă ̣c nhầ m lẫn đố i với ngƣời đo ̣c và hiể u, cài đặt thuật toán.
Tính hiệu quả: thuâ ̣t toán đƣơ ̣c xem là hiê ̣u quả nế u nhƣ nó có khả năng giải quyế t hiê ̣u
quả bài toán đặt ra trong thời gian hoặc các điều kiện cho phép trên thực tế đáp ứn g đƣơ ̣c yêu
cầ u của ngƣời dùng.
Tính phổ quát : thuâ ̣t toán đƣơ ̣c go ̣i là có tiń h phố quát
quyế t đƣơ ̣c mô ̣t lớp các bài toán tƣơng tƣ̣.


(phổ biế n ) nế u nó có thể giải

Ngoài ra mỗi thuật toán theo định nghĩa đều nhận các giá trị đầu vào đƣợc gọi chung là
các giá trị dữ liệu Input. Kế t quả của thuâ ̣t toán (thƣờng là mô ̣t kế t quả cu ̣ thể nào đó tùy theo
các bài toán và thuật toán cụ thể) đƣơ ̣c go ̣i là Output.
2. Biể u diễn thuâ ̣t toán
Thƣờng có hai cách biểu diễn một thuật toán, cách thứ nhất là mô tả các bƣớc thực hiện
của thuật toán, cách thứ hai là sử dụng sơ đồ giải thuật.
2.1. Mô tả các bƣớc thực hiện
Để biểu diễn thuật toán ngƣời ta mô tả chính xác các bƣớc thực hiện của thuật toán,

2


ғ
ғ
%jLJLҧQJP{QKӑF
3KkQ
W
Õ
F
K
W
KL
r
W

Nr


YD

ÿiQK
J
L
i
J
L
ҧL

W
KXұ
W
Ғ
ғ
Ví dө: mô tҧthuұ
WWRiQWuPѭ
ӟc sӕchung lӟn nhҩ
t cӫa hai sӕnguyên.
Input: Hai sӕnguyên a, b.
Output: ѬӟF

V
ӕ
F
KXQJ

O
ӟQ
QKҩ

W

F
ӫD

D
, b.
Thuұt toán:
%ѭѫ
F

1: 1r
ғ
X
D
=b thì USCLN(a, b)=a.
ғ
%ѭѫ
F

2: 1r
ғ
X
D

> b thì tìm USCLN cӫa a-b và b, quay lҥ
i Eѭѫ
F

1;

ғ
ғ
%ѭѫ
F

3: NӃ
u a < b thì tìm USCLN cӫa a và b-a, quay lҥ
i Eѭѫ
F

1;
ғ
ғ
Ғ
6ӱGөQJ
Vѫ
ÿ{

(OѭXÿӗ
) JLҧLWKXұW
(flowchart)
Ѵ
Ѵ
Ѵ
Ѻ
0{W

W
U
RQJ


QKѭ
QJ

F
D
F
K
SK{

EL
r
ғ
Q
ÿr

EL
r
X
GL
r
Q

W
KXk
W

W
RD
Q

O
D

V
ѭ

GXQ
J

V
ѫ
ÿ{
Ғ

W
KXk
W

W
RD
Q

ҕ
ҕ
ҕ
ҕ
Ѵ
Ѻ
ғ
ғ

Ғ
ғ
(Algorithm Flowchart).
Ѵ
6ѫ
ÿ{
Ғ

W
KXk
W

W
RD
Q
V
ѭ

GXQ
J

F
D
F

N\

KL
r
X



Q
NK{
ғ
L

F
ѫ
ED
Q
ÿr

W
D
R

W
KD
QK
P{W

P{
W
D

PD
QJ

ҕ

ҕ
ҕ
ҕ
ҕ
Ѵ
Ѵ
Ѵ
ғ
ғ
ғ
Ғ
ҒK
W
t
QK
Ku
QK
W
KӭF
(F
i
F
K
Qj
\

U
}
U
j

QJ

KѫQ
V
R
YӟL

YL
Ӌ
F

P{
W
ҧ

F
i
F

EѭӟF

W
KӵF

KL
Ӌ
Q
W
KXұ
W


W
Ri
Q )F
ӫD

W
KXk
W

W
RD
Q. &K~QJ

W
D

F
y
W


Ku
QK
GXQJ

YL
Ӌ
F


V
ӱ
GөQJ

V
ѫ
ÿӗ
J
L
ҧ
L

W
KXұ
W

ÿӇ

P{
W
ҧ

W
KXұ
W

W
Ri
Q
J

L
ӕQJ

ҕ
ғ
Ѵ
QKѭ
GX
QJ

F
D
F

ED
Q
YH

ÿr

P{
W
D

F
k
ғ
X
W
U

X
F

F
X
D

F
D
F

W
R
D

QKD
.
Ѵ
Ѵ
Ѵ
Ѻ
Ғ
ғ
ғ
ғ
Ғ
Ғ
&i
F


NKӕL

F
ѫ
E
ҧ
Q
F
ӫD

PӝW

V
ѫ
ÿӗ
W
KXұ
W

W
Ri
Q

Bắt đầu

1
Câu lệnh

Kết thúc


2

3

4

Điều kiện

Đ

S
5

Nhập xuất dữ liệu

ғ
.K{
L

1: .K{
ғ
L


ғ
W

ÿk
Ғ
X

W
KXk
W

W
RD
Q, F


F
y
GX\

QKҩ
W

PӝW

ÿѭӡQJ

U
D
;
ҕ
ғ
ғ
.K{
L

2: .K{

ғ
L

Nr
ғ
W

W
KX
F

W
KXk
W

W
RD
Q, F
y
W


F
y
QKL
Ӆ
X
ÿѭӡQJ

Yj

R;
ҕ
ғ
ғ
KhӕL

3: 7KѭF

KL
r
Q

F
k
X
O
Ӌ
nh (F
y
W


O
j

PӝW

KRһ
F


QKL
Ӆ
X
F
k
X
O
Ӌ
QK); J
{
Ғ
P
P{W

ÿѭѫ
QJ

YD
R
YD

ҕ
ҕ
ҕ
Ғ
Ғ
Ғ
P{W

ÿѭѫ

QJ

U
D
;
ҕ
Ғ
Ѵ
Ѵ
Ѵ
Khӕi 4: 5Ӂ

QKi
QK, NL
r
P
W
U
D

EL
r
X
W

F

ÿL
Ӆ
u kiӋ

n (EL
r
X
W

F

%RRO
H
D
Q), Qr
ғ
X
EL
Ӈ
u thӭF

ÿX
QJ

ғ
ғ
ғ
W
KXk
W

W
RD
Q

V
H

ÿL

W
KH
R
QKD
QK
Ĉ~QJ
(True), nӃ
X
EL
Ӈ
u thӭF

V
D
L

W
KXk
W

W
RD
Q
V
H


ÿL

W
KH
R
QKD
QK
6D
L

ҕ
ҕ
Ѻ
Ѻ
ғ
ғ
ғ
ғ
(False).

3


Bài giảng môn học: Phân tích thiế t kế và đánh giá giải thuật
Khố i 5: Các câu lệnh nhập và xuất dữ liệu.
3. Độ phức tạp thuật toán – Algorithm Complexity
3.1. Các tiêu chí đánh giá thuật toán
Thông thƣờng để đánh giá mức độ tốt, xấu và so sánh các thuật toán cùng loại, có thể
dựa trên hai tiêu chuẩ n:

+ Thuâ ̣t toán đơn giản, dễ hiể u, dễ cài đă ̣t.
+ Dựa vào thời gian thực hiện và tài nguyên mà thuật toán sử dụng để thực hiện trên các
bộ dữ liệu.
Trên thực tế các thuật toán hiệu quả thì không dễ hiểu, các cài đặt hiệu quả cũng không
dễ dàng thực hiện và hiểu đƣợc một cách nhanh chóng. Và một điều có vẻ nghịch lý là các
thuật toán càng hiệu quả thì càng khó hiểu, cài đặt càng phức tạp lại càng hiệu quả (không
phải lúc nào cũng đúng). Vì thế để đánh giá và so sánh các thuật toán ngƣời ta thƣờng dựa
trên độ phức tạp về thời gian thực hiện của thuật toán, gọi là độ phức tạp thuật toán
(algorithm complexity). Về bản chất độ phức tạp thuật toán là một hàm ƣớc lƣợng (có thể
không chính xác) số phép tính mà thuật toán cần thực hiện (từ đó dễ dàng suy ra thời gian
thực hiện của thuật toán) đối với một bộ dữ liệu input có kích thƣớc N. N có thể là số phần tử
của mảng trong trƣờng hợp bài toán sắp xếp hoặc tìm kiếm, hoặc có thể là độ lớn của số trong
bài toán kiểm tra số nguyên tố chẳng hạn.
3.2. Đánh giá thời gian thƣ ̣c hiêṇ thuâ ̣t toán
Để minh họa việc đánh giá độ phức tạp thuật toán ta xem xét ví dụ về thuật toán sắp xếp
chọn (selection sort) và sắp xếp đổi chỗ trực tiếp (exchange sort) nhƣ sau:
Cài đặt của thuật toán sắp xếp chọn:
for(i=0;i{
min_idx = i;
for(j=i+1;jif(a[j]min_idx = j;
if(min_idx!=i)
{
temp = a[i];
a[i] = a[min_idx];
a[min_idx] = temp;
}


4


Bài giảng môn học: Phân tích thiế t kế và đánh giá giải thuật
}
Số phép tính thuật toán cần thực hiện đƣợc tính nhƣ sau:
(N-1) + (N-2) + … + 2 + 1 = N*(N-1)/2.
Phân tích chi tiết hơn thì N*(N-1)/2 là số phép toán so sánh cần thực hiện, còn số lần
thực hiện đổi chỗ hai phần tử (số nguyên) tối đa của thuật toán là N.
Cài đặt của thuật toán sắp xếp đổi chỗ trực tiếp:
for(i=0;ifor(j=i+1;jif(a[j] < a[i])
{
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
Tƣơng tự đối với thuật toán sắp xếp chọn ta có số phép toán thƣ̣c hiê ̣n là : (N-1) + (N-2)
+ …+2 +1 = N*(N-1)/2. Chi tiết hơn, N*(N-1)/2 là số lần so sánh thuật toán thực hiện, và
cũng là số lần đổi chỗ hai phần tử (hai số nguyên) tối đa của thuật toán.
Trong trƣờng hợp trung bình, thuật toán sắp xếp chọn có xu hƣớng tốt hơn so với sắp
xếp đổi chỗ trực tiếp vì số thao tác đổi chỗ ít hơn, còn trong trƣờng hợp tốt nhất thì nhƣ nhau,
trƣờng hợp tồi nhất thì chắc chắn thuật toá n sắp xếp chọn tốt hơn, do đó có thể kết luận thuật
toán sắp xếp chọn nhanh hơn so với thuật toán sắp xếp đổi chỗ trực tiếp.
3.3. Các định nghĩa hình thức về độ phức tạp thuật toán
Gọi f, g là các hàm không giảm đinh
̣ nghiã trên tâ ̣p các số nguyên dƣơng . (chú ý là tất
cả các hàm thời gian đều thỏa mãn các điều kiện này ). Chúng ta nói rằng hàm f(N) là O(g(N))
(đo ̣c là: f là O lớn của g) nế u nhƣ tồ n ta ̣i mô ̣t hằ ng số c và N0:


N  N0 ; f ( N )  c.g ( N )
Phát biểu thành lời nhƣ sau : f(N) là O(g(N)) nế u tồ n ta ̣i c sao cho hầ u hế t phầ n đồ thi ̣
của hàm f nằm dƣới phần đồ thị của hàm c *g. Chú ý là hàm f tăng nhiều nhất là nhanh b ằng
hàm c*g.
Thay vì nói f (N) là O(g(N)) chúng ta thƣờng viết là f (N) = O(g(N)). Chú ý rằng đẳng
thƣ́c này không có tính đố i xƣ́ng có nghiã là chúng ta có thế viế t ngƣơ ̣c la ̣i
O(g(N)) = f(N)
nhƣng không thể suy ra g(N) = O(f(N)).
Định nghĩa trên đƣợc gọi là ký hiệu O lớn (big-O notation) và thƣờng đƣợc sử dụng để
chỉ định các chặn trên của hàm tăng.

5


Bài giảng môn học: Phân tích thiế t kế và đánh giá giải thuật
Chẳ ng ha ̣n đố i với ví du ̣ về sắ p xế p bằ ng cho ̣n ta có f(N) = N*(N-1)/2 = 0.5N2 – 0.5N
chúng ta có thể viết là f(N) = O(N2). Có nghĩa là hàm f không tăng nhanh hơn hàm N 2.
Chú ý rằng thậm chí hàm f chính xác có công thức nhƣ thế nào không cho chúng ta câu
trả lời chính xác của câu hỏi “Chƣơng trình có thời gian thƣ̣c hiê ̣n là bao lâu trên máy tiń h của
tôi?”. Nhƣng điề u quan tro ̣ng là qua đó chúng ta biế t đƣơ ̣c hàm thời gian thƣ̣c hiê ̣n của thuâ ̣t
toán là hàm bậc hai . Nế u chúng ta tăng kić h thƣớc input lên 2 lầ n, thời gian thƣ̣c hiê ̣ n của
chƣơng triǹ h sẽ tăng lên xấ p xỉ 4 lầ n không phu ̣ thuô ̣c vào tố c đô ̣ của máy.
Chă ̣n trên f(N) = O(N2) cho chúng ta kế t quả gầ n nhƣ thế – nó đảm bảo rằng độ tăng của
hàm thời gian nhiều nhất là bậc hai.
Do đó chúng ta sẽ sƣ̉ du ̣ng ký pháp O lớn để mô tả thời gian thƣ̣c hiê ̣n của thuâ ̣t toán
(và đôi khi cả bộ nhớ mà thuật toán sử dụng). Đối với thuật toán trong ví dụ 2 chúng ta có thể
nói “độ phức tạp thời gian của thuật toán là O(N2) hoă ̣c ngắ n gọn là “thuật toán là O(N2)”.
Tƣơng tƣ̣ chúng ta có các đinh
̣ nghiã  (omega)và  (theta):

Chúng ta nói rằng hàm f(N) là  (g(N)) nế u nhƣ g(N) = O(f(N)), hay nói cách khác hàm
f tăng ít nhấ t là nhanh bằ ng hàm g.
Và nói rằng hàm f (N) là  (g(N)) nế u nhƣ f (N) = O(g(N)) và g(N) = O(f(N)), hay nói
cách khác cả hai hàm xấp xỉ nhƣ nhau về độ tăng.
Hiể n nhiên là cách viế t  là để chỉ ra chặn dƣới và  là để chỉ ra một giới hạn chặt chẽ
của một hàm. Còn có nhiều giới hạn khác nữa nhƣng đây là các giới hạn mà chúng ta hay gặp
nhấ t.
Mô ̣t vài ví du ̣:

0.5N2 – 0.5N = O(N2)

47 N*log(N) = O(N*log(N))

N*log(N) + 1000047N =  (N*log(N))

Tấ t cả các hàm đa thƣ́c bâ ̣c k đề u là O(Nk)

Độ phức tạp thời gian c ủa thuật toán sắp xếp chọn và sắp xếp đổi chỗ
trƣ̣c tiế p là  (N2)

Nế u mô ̣t thuâ ̣t toán là O(N2) thì nó cũng là O(N5)

Mỗi thuâ ̣t toán sắ p xế p dƣ̣a trên so sánh có độ phức tạp tối ƣu là 
(N*log(N))

Thuâ ̣t toán sắ p xế p MergeSort có số thao tác so sánh là N *log(N). Do
đó đô ̣ phƣ́c ta ̣p thời gian của MergeSort là  (N*log(N)) có nghĩa là MergeSort là
tiê ̣m câ ̣n với thuâ ̣t toán sắ p xế p tố i ƣu.
Khi xem xét so sánh các thuật toán cùng loại ngƣời ta thƣờng xét độ phức tạp của thuật
toán trong các trƣờng hợp : trung biǹ h (average case), trƣờng hơ ̣p xấ u nhấ t (the worst case) và

trƣờng hơ ̣p tố t nhấ t (the best case).

6


Bài giảng môn học: Phân tích thiế t kế và đánh giá giải thuật
3.4. Các lớp thuật toán
Khi chúng ta nói về đô ̣ phƣ́c ta ̣p thời gian / không gian nhớ của mô ̣t thuâ ̣t toán thay vì sƣ̉
dụng các ký hiệu hình thức  (f(n)) chúng ta có thể đơn giản đề cập tới lớp của hàm f . Ví dụ
f(N) =  (N) chúng ta sẽ nói thuật toán là tuyến tính (linear). Có thể tham khảo thêm:
f(N) = 1: hằ ng số (constant)
f(N) =  (log(N)): logarit
f(N) =  (N): tuyế n tiń h (linear)
f(N) =  (N*log(N)): N log N
f(N) =  (N2): bâ ̣c hai (quadratic)
f(N) =  (N3): bâ ̣c 3 (cubic)
f(N) = O(Nk) với k là mô ̣t số nguyên dƣơng: đa thƣ́c (polynomial)
f(N) =  (bN): hàm mũ (exponential)
Đối với các bài toán đồ thị độ phức tạp
thƣớc của đồ thi”.̣

 (V+E) có nghĩa là “tuyến tính đối với kích

Xác định thời gian thực hiện từ một giới hạn tiệm cận
Đối với hầu hết các thuật toán chúng ta có thể gặp các hằng số bị che đi bởi cách viết O
hoă ̣c b thƣờng là khá nhỏ . Chăng ha ̣n nế u đô ̣ phƣ́c ta ̣p thuâ ̣t toán là  (N2) thì chúng ta sẽ
mong muố n chiń h xác đô ̣ phƣ́c ta ̣p thời gian là 10N2 chƣ́ không phải là 107N2.
Có nghĩa là nếu hằng số là lớn thì thƣờng là theo một cách nào đó liên quan tới một vài
hằ ng số của bài toán . Trong trƣờng hơ ̣p này tố t nhấ t l à gán cho hằng đó một cái tên và đƣa nó
vào ký hiệu tiệm cận của hằng số đó.

Ví dụ: bài toán đếm số lần xuất hiện của mỗi ký tự trong một xâu có N ký tự . Mô ̣t thuâ ̣t
toán cơ bản là duyệt qua toàn bộ xâu đối với mỗ i ký tƣ̣ để thƣ̣c hiê ̣n đế m xem ký tƣ̣ đó xuấ t
hiê ̣n bao nhiêu lầ n . Kích thƣớc của bảng chữ cái là cố định (nhiề u nhấ t là 255 đố i với ngôn
ngƣ̃ lâ ̣p triǹ h C ) do đó thuâ ̣t toán là tuyế n tiń h đố i với N . Nhƣng sẽ là tố t hơn nế u viế t là đô ̣
phƣ́c ta ̣p của thuâ ̣t toán là  (S*N) trong đó S là số phầ n tƣ̉ của bảng chƣ̃ cái sƣ̉ du ̣ng . (Chú ý
là có một thuật toán tốt hơn để giải bài toán này với độ phức tạp là  (S + N).
Trong các cuô ̣c thi lâ ̣p trình mô ̣t thuâ ̣t toán thƣ̣c hiê ̣n 1000000000 phép nhân có thể
không thỏa mañ ràng buô ̣c thời gian. Chúng ta có thể tham khảo bảng sau để biết thêm:
Độ phức tạp

Giá trị N lớn nhất

 (N)

100 000 000

 (N log N)

40 000 000

 (N2)

10 000

 (N3)

500

7



Bài giảng môn học: Phân tích thiế t kế và đánh giá giải thuật
 (N4)

90

 (2N)

20

 (N!)

11

Thời gian thƣ ̣c hiêṇ của các thuâ ̣t toán có đô ̣ phƣ́c ta ̣p khác nhau
O(Log(N))

10-7 giây

O(N)

10-6 giây

O(N*Log(N))

10-5 giây

O(N2)

10-4 giây


O(N6)

3 phút

O(2N)

1014 năm

O(N!)

10142 năm

Chú ý về phân tích thuâ ̣t toán.
Thông thƣờng khi chúng ta triǹ h bày mô ̣t thuâ ̣t toán cách tố t nhấ t để nói về đô ̣ phƣ́c ta ̣p
thời gian của nó là sƣ̉ du ̣ng các chă ̣n  . Tuy nhiên trên thƣ̣c tế chúng ta hay dùng ký pháp
big-O – các kiểu khác không có nhiều giá trị lắm , vì cách này rất dễ gõ và cũng đƣợc nhiều
ngƣời biế t đế n và hiể u rõ hơn . Nhƣng đƣ̀ng quên là big -O là chă ̣n trên và thƣờng thì chúng ta
sẽ tìm môt chặn trên càng nhỏ càng tố t.
Ví dụ: Cho mô ̣t mảng đã đƣơ ̣c sắ p A . Hãy xác định xem trong mảng A có hai phần tử
nào mà hiệu của chúng bằng D hay không. Hãy xem đoạn mã chƣơng trình sau:
int j=0;
for (int i=0; i{
while ( (j<N-1) && (A[i]-A[j] > D) )
j++;
if (A[i]-A[j] == D)
return 1;
}
Rấ t dễ để nói rằ ng thuâ ̣t toán trên là O(N2): vòng lặp while bên trong đƣợc gọi đến N

lầ n, mỗi lầ n tăng j lên tố i đa N lầ n . Nhƣng mô ̣t phân tích tố t hơn sẽ cho chúng ta thấ y rằ ng
thuật toán là O(N) vì trong cả thời gian thực hiện của thuật toán lệnh tăng j không chạy nhiều
hơn N lầ n.

8


Bài giảng môn học: Phân tích thiế t kế và đánh giá giải thuật
Nế u chúng ta nói rằ ng thuâ ̣t toán là O(N2) chúng ta vẫn đúng nhƣng nếu nói là thuật
toán là O(N) thì chúng ta đã đƣa ra đƣơ ̣c thông tin chiń h xác hơn về thuâ ̣t toán.
4. Cấ u trúc dƣ̃ liêụ – Data structure
Niklaus Wirth, một lập trình viên và nhà khoa học máy tính, ngƣời phát minh ra ngôn
ngữ lập trình Pascal đã từng nói một câu nói nổi tiếng trong lĩnh vực lập trình: Chƣơng trình
(Programs) = Cấu trúc dữ liệu (Data Structures) + Giải thuật (Algorithms). Câu nói này nói
lên bản chất của việc lập trình là đi tìm một cấu trúc dữ liệu phù hợp để biểu diễn dữ liệu của
bài toán và từ đó xây dựng giải thuật phù hợp với cấu trúc dữ liệu đã chọn. Ngày nay với sự
phát triển của các kỹ thuật lập trình, câu nói của Wirth không hẳn còn đúng tuyệt đối nữa
nhƣng nó vẫn phản ánh sự gắn kết và tầm quan trọng của các cấu trúc dữ liệu và giải thuật.
Cấu trúc dữ liệu đƣợc sử dụng để biểu diễn dữ liệu còn các giải thuật đƣợc sử dụng để thực
hiện các thao tác trên các dữ liệu của bài toán nhằm hoàn thành các chức năng của chƣơng
trình
5. Các chiến lƣợc thiết kế thuật toán.
Không có mô ̣t phƣơng pháp nào có thể giúp chúng ta xây dƣ̣ng (thiế t kế ) nên các thuâ ̣
toán cho tất cả các loại bài toán . Các nhà khoa h ọc máy tính đã nghiên cƣ́u và đƣa ra các
chiế n lƣơ ̣c thiế t kế các giải thuâ ̣t chung nhấ t áp du ̣ng cho các loa ̣i bài toán khác nhau.
5.1. Duyệt toàn bộ (Exhausted search)
Chiến lƣợc duyệt toàn bộ là chiến lƣợc mà mỗi lập trình viên phải nghĩ đến đầu tiên khi
giải quyết bất cứ bài toán nào. Trong phƣơng pháp duyệt toàn bộ, chúng ta sẽ xem xét tất cả
các ứng cử viên thuộc một không gian có thể có của bài toán để xem đó có phải là nghiệm của
bài toán hay không. Phƣơng pháp này yêu cầu có một hàm kiểm tra xem một ứng cử viên nào

đó có phải là nghiệm của bài toán hay không. Mặc dù dễ hiểu song phƣơng pháp này không
phải là dễ thực hiện, và đặc biệt là không hiệu quả đối với các bài toán mà kích thƣớc input
lớn. Có nhiều phƣơng pháp cải tiến hiệu năng của phƣơng pháp duyệt toàn bộ và chúng ta sẽ
xem xét kỹ hơn trong chƣơng 3.
5.2. Đệ qui quay lui – Backtracking
Chiến lƣợc đệ qui quay lui là một chiến lƣợc xây dựng thuật toán dựa trên quan hệ đệ
qui. Nghiệm của bài toán đƣợc mô hình hóa dƣới dạng một vecto, mỗi thành phần của vecto
nghiệm sẽ có một tập giá trị có thể nhận và thuật toán sẽ tiến hành các bƣớc gán các giá trị có
thể cho các thành phần của nghiệm để xác định đúng nghiệm của bài toán. Mặc dù không phải
bài toán nào cũng có thể áp dụng song các thuật giải dựa trên phƣơng pháp đệ qui quay lui
luôn có vẻ đẹp từ sự ngắn gọn, súc tích mà nó mang lại.
5.3. Chia để tri (Divide
and Conquer)
̣
Chiế n lƣơ ̣c chia để tri ̣là mô ̣t chiế n lƣơ ̣c quan tro ̣ng trong viê ̣c thiế t kế các giải thuâ ̣t . Ý
tƣởng của chiế n lƣơ ̣c này nghe rấ t đơn giản và dễ nhâ ̣n thấ y , đó là: khi cầ n giải quyế t mô ̣t bài

9


Bài giảng môn học: Phân tích thiế t kế và đánh giá giải thuật
toán, ta sẽ tiế n hành chia bài toán đó thành các bài toán nhỏ hơn, giải các bài toán nhỏ hơn đó,
sau đó kế t hơ ̣p nghiê ̣m của các bài toán nhỏ hơn đó la ̣i thành nghiê ̣m của bài toán ban đầ u .
Tuy nhiên vấ n đề khó khăn ở đây nằ m ở hai yế u tố : làm thế nào để chia tách bài toán
mô ̣t cách hơ ̣p lý thành các bài toán con , vì nếu các bài toán con lại đƣợc giải quyết bằng các
thuâ ̣t toán khác nhau thì sẽ rất phức tạp, yế u tố thƣ́ hai là viê ̣c kế t hơ ̣p lời giải của các bài toá n
con sẽ đƣơ ̣c thƣ̣c hiê ̣n nhƣ thế nào ?.
Các thuật toán sắp xếp trộn (merge sort), sắ p xế p nhanh (quick sort) đều thuộc loại thuật
toán chia để trị (các thuật toán này đƣợc trình bày ở chƣơng 3).
Ví dụ[6, trang 57]: Trong ví du ̣ này chúng ta sẽ xem xét thuật toán tính aN .

Để tính aN ta để ý công thƣ́c sau:
a

N

1 nÕu N = 0
(a ) nÕu N ch½n
a* (aN/2 )2 nÕu N lÎ
N/2 2

Tƣ̀ công thƣ́c trên ta suy ra cài đă ̣t của thuâ ̣t toán nhƣ sau:
int power(int a, int n)
{
if(n==0)
return 1;
else{
int t = power(a, n/2);
if(n%2==0)
return t*t;
else
return a*t*t;
}
}
5.4. Chiế n lƣơ ̣c tham lam (Greedy)
Chiến lƣợc tham lam là một chiến lƣợc xây dựng thuật toán tìm nghiệm tối ƣu cục bộ
cho các bài toán tối ƣu nhằm đạt đƣợc nghiệm tối ƣu toàn cục cho cả bài toán (trong trƣờng
hợp tổng quát). Trong trƣờng hợp cho nghiệm đúng, lời giải của chiến lƣợc tham lam thƣờng
rất dễ cài đặt và có hiệu năng cao (độ phức tạp thuật toán thấp).
Chú ý: Trong mô ̣t số bài toán nếu xây dựng đƣợc hàm chọn thích hợp có thể cho nghiệm
tố i ƣu. Trong nhiề u bài toán, thuâ ̣t toán tham ăn chỉ cho nghiê ̣m gầ n đúng với nghiê ̣m tố i ƣu.


10


Bài giảng môn học: Phân tích thiế t kế và đánh giá giải thuật
5.5. Qui hoạch động (Dynamic Programming)
Qui hoạch động là chiến lƣợc xây dựng thuật toán để giải quyết các bài toán tối ƣu, có
thể đòi hỏi của bài toán không phải là các giá trị quá chi tiết mà chỉ ở dạng giá trị lớn nhất/nhỏ
nhất là bao nhiêu chứ không đòi hỏi cụ thể khi nào, ở đâu để có thể đạt đƣợc giá trị đó. Trong
chiến lƣợc qui hoạch động chúng ta sẽ xây dựng các quan hệ đệ qui của bài toán, bài toán gốc
sẽ có lời giải dựa trên các bài toán con (sub problems) dựa trên quan hệ đệ qui. Các thuật toán
qui hoạch động thƣờng sử dụng các mảng để lƣu lại giá trị nghiệm của các bài toán con và có
hai cách tiếp cận: bottom up và top down.
6. Bài tập
Bài tập 1: Xây dƣ̣ng sơ đồ giải thuâ ̣t cho bài toán tính số Fibonaci thƣ́ N , biế t rằ ng daỹ
số Fibonaci đƣơ ̣c đinh
̣ nghiã nhƣ sau:
F[0] = F[1] = 1, F[N] = F[N-1] + F[N-2] với N ≥ 2.
Bài tập 2: Xây dƣ̣ng sơ đồ giải thuâ ̣t cho bài toán tiń h biể u thƣ́c:

x  x  ...  x , với N số x thƣ̣c nằ m trong các dấ u căn bâ ̣c hai , N và x nhâ ̣p tƣ̀ bàn
phím.
Bài tập 3: Trong mô ̣t ma trâ ̣n hai chiề u cấ p MxN , mô ̣t phầ n tƣ̉ a [i][j] đƣơ ̣c go ̣i là điể m
yên ngƣ̣a của ma trâ ̣n (saddle point) nế u nhƣ nó là phầ n tƣ̉ nhỏ nhấ t trên hàng i và phầ n tƣ̉ lớn
nhấ t trên cô ̣t j của ma trâ ̣n. Chẳ ng ha ̣n a[2][0] = 7 là mô ̣t phầ n tƣ̉ yên ngƣ̣a trong ma trâ ̣n sau:
1 2 3
4 5 6


7 8 9 


Hãy viết chƣơng trình tìm tất cả các điểm yên ngựa của một ma trận nhập vào từ bàn
phím và đƣa ra độ phức tạp của thuật toán.
Bài tập 4: Cho mô ̣t ma trâ ̣n kí ch thƣớc MxN gồ m các số nguyên (có cả số âm và
dƣơng). Hãy viết chƣơng trình tìm ma trận con của ma trận đã cho sao cho tổng các phần tử
trong ma trâ ̣n con đó lớn nhấ t có thể đƣơ ̣c (bài toán maximum sum plateau). Hãy đƣa ra đán h
giá về độ phức tạp của thuật toán sử dụng.
Bài tập 5: Viế t chƣơng trình nhâ ̣p vào các hê ̣ số của mô ̣t đa thƣ́c (giả sử các hệ số là
nguyên và đa thƣ́c có biế n x là mô ̣t số nguyên ) và một giá trị x 0. Hãy tính giá trị của đa thức
theo công thƣ́c Horner sau:
Nế u f(x) = an*xn + an-1*xn-1+ .. +a1*x + a0 thì
f(x) = a0 + x*(a1+x*(a2+x*(….+x(an-1+an*x)…) (Công thƣ́c Horner).
Bài tập 6: Cho 4 hình hộp kích thƣớc bằng nhau , mỗi mă ̣t của hình hô ̣p đƣơ ̣c tô bằ ng 1
trong 4 màu xanh, đỏ, tím, vàng. Hãy đƣa ra tất cả các cách xế p các hình hô ̣p thành 1 dãy sao
cho khi nhiǹ theo các phiá trên xuố ng , đằ ng trƣớc và đằ ng sau của daỹ đề u có đủ cả 4 màu
xanh, đỏ, tím vàng.

11


Bài giảng môn học: Phân tích thiế t kế và đánh giá giải thuật
Bài tập 7: Hãy viết chƣơng trình nhanh nhất có thể đƣợc để in ra tất cả các số nguyên
số có hai chƣ̃ số .
Bài tập 8: Áp dụng thuật toán sàng để in ra tất cả các số nguyên tố nhỏ hơn N.

12


Bài giảng môn học: Phân tích thiế t kế và đánh giá giải thuật
CHƢƠNG II: SẮP XẾP (SORTING) VÀ TÌM KIẾM (SEARCHING)

1. Bài toán sắp xếp
1.1. Sắ p xế p trong (Internal Sorting)
Sắp xếp đƣợc xem là một trong những lĩnh vực nghiên cứu cổ điển của khoa học máy
tính. Trƣớc khi đi vào các thuật toán chi tiết chúng ta cần nắm vững một số khái niệm cơ bản
sau:
+ Một trƣờng (field) là một đơn vị dữ liệu nào đó chẳng hạn nhƣ tên, tuổi, số điện thoại
của một ngƣời ...
+ Một bản ghi (record) là một tập hợp các trƣờng
+ Một file là một tập hợp các bản ghi
Sắp xếp (sorting) là một quá trình xếp đặt các bản ghi của một file theo một thứ tự nào
đó. Việc xếp đặt này đƣợc thực hiện dựa trên một hay nhiều trƣờng nào đó, và các thông tin
này đƣợc gọi là khóa xắp xếp (key). Thứ tự của các bản ghi đƣợc xác định dựa trên các khóa
khác nhau và việc sắp xếp đối đƣợc thực hiện đối với mỗi khóa theo các thứ tự khác nhau.
Chúng ta sẽ tập trung vào các thuật toán xắp xếp và giả sử khóa chỉ gồm 1 trƣờng duy nhất.
Hầu hết các thuật toán xắp xếp đƣợc gọi là các thuật toán xắp xếp so sánh: chúng sử dụng hai
thao tác cơ bản là so sánh và đổi chỗ (swap) các phần tử cần sắp xếp.
Các bài toán sắp xếp đơn giản đƣợc chia làm hai dạng.
Sắ p xế p trong (internal sorting): Dƣ̃ liê ̣u cầ n sắ p xế p đƣơ ̣c lƣu đầ y đủ trong bô ̣ nhớ
trong để thực hiện thuật toán sắp xếp.
1.2. Sắ p xế p ngoài (External Sorting)
Sắ p xế p ngoài (external sorting): Dƣ̃ liê ̣u cầ n sắ p xế p có kích thƣớc quá lớn và không
thể lƣu vào bô ̣ nhớ trong để sắ p xế p , các thao tác truy cập dữ liệu cũng mất nhiều thời gian
hơn.
Trong pha ̣m vi của môn ho ̣c này chúng ta chỉ xem xét các thuâ ̣t toán sắ p xế p trong . Cụ
thể dƣ̃ liê ̣u sắ p xế p sẽ là mô ̣t mảng các bản ghi (gồ m hai trƣờng chính là trƣờng dƣ̃ liê ̣u và
trƣờng khóa), và để tập trung vào các thuật toán chúng ta chỉ xem xét các trƣờng khóa của các
bản ghi này , các ví dụ minh họa và cài đặt đều đƣợc thực hiện trên các mảng số nguyên , coi
nhƣ là trƣờng khóa của các bản ghi.
1.3. Sắ p xế p gián tiếp
Khi các bản ghi có kích thƣớc lớn việc hoán đổi các bản ghi là rất tốn kém, khi đó để

giảm chi phí ngƣời ta có thể sử dụng các phƣơng pháp sắp xếp gián tiếp. Việc này có thể đƣợc
thực hiện theo nhiều cách khác nhau và môt trong những phƣơng pháp đó là tạo ra một file
mới chứa các trƣờng khóa của file ban đầu, hoặc con trỏ tới hoặc là chỉ số của các bản ghi ban
đầu. Chúng ta sẽ sắp xếp trên file mới này với các bản ghi có kích thƣớc nhỏ và sau đó truy
cập vào các bản ghi trong file ban đầu thông qua các con trỏ hoặc chỉ số (đây là cách làm
thƣờng thấy đối với các hệ quản trị cơ sở dữ liệu).

13


Bài giảng môn học: Phân tích thiế t kế và đánh giá giải thuật
Ví dụ: chúng ta muốn sắp xếp các bản ghi của file sau đây:
Index

Dept

Last

First

Age ID number

1

123

Smith

Jon


3

234-45-4586

2

23

Wilson

Pete

4

345-65-0697

3

2

Charles

Philip 9

508-45-6859

4

45


Shilst

Greg

234-45-5784

8

Sau khi sắp xếp xong để truy cập vào các bản ghi theo thứ tự đã sắp xếp chúng ta sử
dụng thứ tự đƣợc cung cấp bởi cột index (chỉ số). Trong trƣờng hợp này là 3, 2, 4, 1. (chúng
ta không nhất thiết phải hoán đổi các bản ghi ban đầu).
1.3. Các tiêu chuẩn đánh giá một thuật toán sắp xếp
Các thuật toán sắp xếp có thể đƣợc so sánh với nhau dựa trên các yếu tố sau đây:
+ Thời gian thực hiện (run-time): số các thao tác thực hiện (thƣờng là số các phép so
sánh và hoán đổi các bản ghi).
+ Bộ nhớ sử dụng (Memory): là dung lƣợng bộ nhớ cần thiết để thực hiện thuật toán
ngoài dung lƣợng bộ nhớ sử dụng để chứa dữ liệu cần sắp xếp.
+ Một vài thuật toán thuộc loại “in place” và không cần (hoặc cần một số cố định) thêm
bộ nhớ cho việc thực hiện thuật toán.
+ Các thuật toán khác thƣờng sử dụng thêm bộ nhớ tỉ lệ thuận theo hàm tuyến tính hoặc
hàm mũ với kích thƣớc file sắp xếp.
+ Tất nhiên là bộ nhớ sử dụng càng nhỏ càng tốt mặc dù việc cân đối giữa thời gian và
bộ nhớ cần thiết có thể là có lợi.
+ Sự ổn định (Stability):Một thuật toán đƣợc gọi là ổn định nếu nhƣ nó có thể giữ đƣợc
quan hệ thứ tự của các khóa bằng nhau (không làm thay đổi thứ tự của các khóa bằng nhau).
Chúng ta thƣờng lo lắng nhiều nhất là về thời gian thực hiện của thuật toán vì các thuật
toán mà chúng ta bàn về thƣờng sử dụng kích thƣớc bộ nhớ tƣơng đƣơng nhau.
Ví dụ về sắp xếp ổn định: Chúng ta muốn sắp xếp file sau đây dự trên ký tự đầu của các
bản ghi và dƣới đây là kết quả sắp xếp của các thuật toán ổn định và không ổn định:


14


Bài giảng môn học: Phân tích thiế t kế và đánh giá giải thuật

Chúng ta sẽ xem xét tại sao tính ổn định trong các thuật toán sắp xếp lại đƣợc đánh giá
quan trọng nhƣ vậy.
2. Các phƣơng pháp sắp xếp cơ bản
2.1. Sắ p xế p cho ̣n (Selection sort)
Mô tả thuâ ̣t toán:
Tìm phần tử có khóa lớn nhất (nhỏ nhất), đặt nó vào đúng vị trí và sau đó sắp xếp phần
còn lại của mảng.
Sơ đồ thuâ ̣t toán:

15


Bài giảng môn học: Phân tích thiế t kế và đánh giá giải thuật

Bắt đầu
Nhập n, a[0..n-1]
i=0
S

iĐ
vtmin=i
j=i+1

S


jĐ

S

a[j]Đ
vtmin=j
j=j+1

S

vtmin!=i

Đ
Đổi chỗ a[i], a[vtmin]
i=i+1
Kết thúc
Đoạn mã sau minh họa cho thuật toán:
void selection_sort(int a[], int n)
{
int i, j, vtmin;

16


Bài giảng môn học: Phân tích thiế t kế và đánh giá giải thuật
for(i=0; i{

vtmin = i; //biế n vtmin lƣu vi ̣trí phầ n tƣ̉ nhỏ nhấ t a[i..n-1]
for(j=i+1;jif(a[j] < a[vtmin])
vtmin = j;
swap(a[vtmin], a[i]); // hàm đổi chỗ a[vtmin], a[i]
}
}
Ví dụ:

Với mỗi giá trị của i thuật toán thực hiện (n – i – 1) phép so sánh và vì i chạy từ 0 cho tới
(n–2), thuật toán sẽ cần (n-1) + (n-2) + … + 1 = n(n-1)/2 tức là O(n2) phép so sánh. Trong mo ̣i
trƣờng hơ ̣p số lầ n so sánh của thuâ ̣t toán là không đổ i . Mỗi lầ n cha ̣y của vòng lă ̣p đố i với biế n
i, có thể có nhi ều nhất một lần đổi chỗ hai phần tử nên số lần đổi chỗ nhiều nhất của thuật
toán là n. Nhƣ vâ ̣y trong trƣờng hơ ̣p tố t nhấ t , thuâ ̣t toán cầ n 0 lầ n đổ i chỗ , trung bình cầ n n /2
lầ n đổ i chỗ và tồ i nhấ t cầ n n lầ n đổ i chỗ .
2.2. Sắ p xế p đổ i chỗ trƣ ̣c tiế p (Exchange sort)
Tƣơng tƣ̣ nhƣ thuâ ̣t toán sắ p xế p bằ ng cho ̣n và rấ t dễ cài đă ̣t (thƣờng bi ̣nhầ m với thuâ ̣t
toán sắp xếp chèn) là thuật toán sắp xếp bằng đổi chỗ trực tiếp (mô ̣t số tài liê ̣u còn gọi là thuật
toán Interchange sort hay Straight Selection Sort ).
Mô tả : Bắ t đầ u xét tƣ̀ phầ n tƣ̉ đầ u tiên a [i] với i = 0, ta xét tấ t cả các phầ n tƣ̉ đƣ́ng sau
a[i], gọi là a[j] với j cha ̣y tƣ̀ i+1 tới n-1 (vị trí cuối cùng). Với mỗi că ̣p a[i], a[j] đó, để ý là a[j]
là phần tử đứng sau a [i], nế u a[j] < a[i], tƣ́c là xảy ra sai khác về vi ̣trí thì ta sẽ đổ i chỗ a [i],
a[j].
Ví dụ minh họa : Giả sử mảng ban đầu là int a [] = {2, 6, 1, 19, 3, 12}. Các bƣớc của
thuâ ̣t toán sẽ đƣơ ̣c thƣ̣c hiê ̣n nhƣ sau:
i=0, j=2: 1, 6, 2, 19, 3, 12

17



Bài giảng môn học: Phân tích thiế t kế và đánh giá giải thuật
i=1, j=2: 1, 2, 6, 19, 3, 12
i=2, j=4: 1, 2, 3, 19, 6, 12
i=3, j=4: 1, 2, 3, 6, 19, 12
i=4, j=5: 1, 2, 3, 6, 12, 19
Kế t quả cuố i cùng: 1, 2, 3, 6, 12, 19.
Sơ đồ thuâ ̣t toán:

Bắt đầu
Nhập n, a[0..n-1]
i=0
S

iĐ
j=i+1

S

jĐ

S

a[j]Đ
Đổi chỗ a[i], a[j]
j=j+1
i=i+1
Kết thúc


Cài đặt của thuật toán:
void exchange_sort(int a[], int n)
{
int i, j;
int tam;
for(i=0; i
18


Bài giảng môn học: Phân tích thiế t kế và đánh giá giải thuật
for(j=i+1;jif(a[j] < a[i])
{
// đổ i chỗ a[i], a[j]
tam = a[i];
a[i] = a[j];
a[j] = tam;
}
}
Độ phức tạp của thuật toán : Có thể thấy rằng so với thuật toán sắp xếp chọn , thuâ ̣t toán
sắ p xế p bằ ng đổ i chỗ trƣ̣c tiế p cầ n số bƣớc so sánh tƣơng đƣơng : tƣ́c là n*(n-1)/2 lầ n so sánh.
Nhƣng số bƣớc đổ i chỗ hai phầ n tƣ̉ cũng bằ ng với số lầ n so sánh : n*(n-1)/2. Trong trƣờng
hơ ̣p xấ u nhấ t số bƣớc đổ i chỗ của thuâ ̣t toán bằ ng với số lầ n so sánh , trong trƣờng hơ ̣p trung
bình số bƣớc đổi chỗ là n *(n-1)/4. Còn trong trƣờng hợp tốt nhất , số bƣớc đổ i chỗ bằ ng 0.
Nhƣ vâ ̣y thuâ ̣t toán sắ p xế p đổ i chỗ trƣ̣c tiế p nói chung là châ ̣m hơn nhiề u so với thuâ ̣t toán
sắ p xế p cho ̣n do số lầ n đổ i chỗ nhiề u hơn.
2.3. Sắ p xế p chèn (Insertion sort)
Mô tả thuâ ̣t toán:

Thuâ ̣t toán dƣ̣a vào thao tá c chính là c hèn mỗi khóa vào một dãy con đã đƣợc sắp xếp
của dãy cần sắp. Phƣơng pháp này thƣờng đƣợc sử dụng trong việc sắp xếp các cây bài trong
quá trình chơi bài.
Sơ đồ giải thuâ ̣t của thuâ ̣t toán nhƣ sau:

19


×