Tải bản đầy đủ (.docx) (1,111 trang)

Giáo trình thuật toán Lý thuyết và bài tập

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 (5.61 MB, 1,111 trang )

THUẬT TOÁN
Dành cho Sinh viên Chuyên gia
THU VIEN DAI HOC NHA TRANG

I
10000173 54

Hĩnh, hơn 900 Bài tập
9Ĩn điên cứu có chon ìoc


¿ạ* ¿à véi
uiị* của CĂÚK^ tét
Ầin vui lịng:

• Khơng xé sách
• Khơng each, viết, vẽ lên sách


Chủ Biên :
Nhóm Biên Dịch :

NGỌC ANH THƯ
NGUYỄN TIẾN* - NGUYỄN VĂN HỒI
NGUYỀN HỮU BÌNH - ĐẶNG XN HƯỜNG
NGƠ QUỐC VIỆT - TRƯƠNG NGỌC VÂN

ịh CTịì.-OẨị

Giáo Trình


THUẬT TỐN
LÝ THUYẾT VÀ BÀI TẬP
Sơ cấp - Trung cấp - Cao cấp
>
>
>

Giáo trình dành cho Sinh viên
Tài liệu tham khảo giảng dạy của Giáo viên
Cẩm nang thuật toán dành cho các chuyên gia
> Nhiều ví dụ, hình, 900 bài tập và hơn 120 bài toán dể bạn trắc nghiệm mức tiếp thu
căn bản về nội dung - tư duy tự kiêm tra

í' p-

......

!

NHÀ XUẤT BẢN THỐNG KÊ


Nhóm Ngọc Anh Thư Press®
------- Trân Trọng Giới Thiệu Tới Bạn Đọc --------------------Cấc Sách Sáp Xuất Ban
1.

XML Nhập Môn - Thực Hành & ửng Dụng

2.


Cấu Trúc Dữ Liệu & Giai Thuật Java

3.

Giáo Trình Lập Trình Hướng Đối Tượng Java

4.

Phần Cứng Máỵ Tính - Kỹ Thuật và Giải Pháp (Tập 1 và 2)

5.

Lập Trình C#

33-333

TllSĩ 137 - 99 - 2001

Lời Nói Đâu


C

Ĩ những CÌ1 sách viết về thuật tốn tuy nghiêm túc song khơng đầy đủ và có
những CÌ1 sách tuy nội dung phong phú song lại khơng nghiêm túc. Giáo
trình Thuật toán, Sơ cấp, Trung cấp, và Cao cấp vừa mang tính tồn diện vừa đầy
đủ. Có thể dùng nó làm sách giáo khoa, cấm nang, sổ tay, và tài liệu tham khảo chung.
Giáo trình Thuật tốn đề cập cả nội dung cố điển lẫn các phát triển hiện đại như phân
tích có khâu trừ và các thuật tốn song song. Phần giải thích tốn học, tuy nghiêm túc,
song vẫn được nêu chi tiết cán thận để mọi tầng lớp độc giả có thế nắm vững. Các chương

được tố chức sao cho chúng bắt đầu vời nội dung sơ cấp rồi tiến dần lên các chú đề cao
cấp hơn.
Mỗi chương tương đối độc lập và có thể dùng như
một
đơn vị học
Các thuật tốn được trình bày theo dạng mã
giả mà mọi người đã
với Fortran, c, hoặc Pascal, đều có thể hiểu
được. Vơ
sơ' ví dụ có
minh họa, hơn 900 bài tập, và 120 bài tốn
điển cứu
thích đáng
mạnh các khía cạnh tốn học lẫn thiết kế kỹ thuật của chú đề.

trình.
quen
hình
nhấn

Giáo trình Thuật tốn thật hừư ích dành cho các bạn Sinh viên tờ khóa học năm cuổì về
các cấu trúc dữ liệu cho đến khóa học sau dại học về các thuật tốn. Sách thực sự là một
cuốn giáo trình trước mắt và một tài liệu tốn học hoặc một cìì cấm nang thiết kế kỹ
thuật ln có mặt trên bàn giấy để bạn tham kháo cho nghề nghiệp của mình sau này.
Với các Giáo viên đang giảng dạy có thế thoải mái tổ chức khóa học dựa trên những
chương cần thiết và được thiết kế tương đối độc lập với nhau, do đó giáo viên có thế' lựa
chọn chất liệu thích hợp nhất hồ trơ cho khóa học mà mình sẽ dạy.
Với các Chuyên gia, sách với nhiều chủ đề đa dạng đà trở thành một cấm nang tuyệt vời
về thuật tốn. Bới hầu hết các thuật tốn mị tá trong sách này đều có tính tiện ích cao, mơ
tá các phương án thay thế thực tiễn đối với một sơ' thuật tốn thiên về lý thuyết, cùng

nhiều vấn đề hay, mới và thú vị dành cho bạn.
Chủng tôi xin trân trọng giới thiệu và rât mong sự đón nhận và động viên của các bạn
đọc để tủ sách Ngọc Anh Thư Press của chúng tôi ngày càng tốt hơn.
Xuân Nhâm Ngọ - 2002
Ngọc Anh Thu Press


6 Mục Lục

Mục Lục
Lời giới thiệu
Giới thiệu 18

Chương 1

LI Thuật tốn ỉ 8
1.2 Phân tích các thuật tốn 23
13
Thiết kế các thuật tốn
1.4 Tóm tắt 34

30

Phần I Căn bản về toán học
Giổi thiệu 40
Chương 2

Sự tăng trưởng của các hàm 42
2.1 Hệ ký hiệu tiệm cận 42
22 Các hệ ký hiệu chuẩn và các hàm chung 52


Chương 3.

Phép lấy tểng 62
3.1 Các tính châ't và cơng thức lấy tổng 62
32 Định cận các phân pháp lấy tổng 66

Chương 4

4.5

4.10

Các phép truy toán 73
4.1 Phương pháp thay thế 74
4.2
52
4.3
5.4 Đồ thị 108
4.4
55 Cây 114
Chưilng 6 Đêm và xác xuâ't ĩ23
6.1 Đếm 123
6.2 Xác
suất 129
4.6
63
Các
biến ngẫu nhiên rịi
rạc 136

6.4 Các
phép phân
phơi nhịthức
4.7và theo cấp số nhân 140
4.8 ★
6.5 Các mặt sấp của phép phân phối nhị thức 146
4.9
6.6 Phân tích xác suất 152

Phần ỉỉ Sắp xếp và thống kề thứ tự 162


Mục Lục

7

4.11
4.12

Nhập đề 163

Chương 7 Sắp xếp đông 166
4.13
1A
Đống 166
7.2 Duy trì tính chất đơng
168
4.14
73
Xây dựng một đống

7.4 Thuật tốn sắp xếp đống 173
7.5 Các hàng đợi ưu tiên 175

171

4.15

Chương 8 Sắp xếp nhanh 180
8.1 Mô tả kiểu sắp xếp nhanh -180
82 Khả năng thực hiện của sắp xếp nhanh 183
83 Các phiên bản ngẫu nhiên hóa của
4.16 sắp xếp nhanh 188
8.4 Phân tích thuật tốn sắp xếp nhanh
191

4.17

Chương 9Sắp xếp trong thời gian tuyến tính
9.1 Các cận dưới để sắp xếp 200
92 Sắp xếp đếm 203
93 Sắp xếp cơ số 206
9.4 Sắp xếp bô 209

4.18
10.1
102
103

Chương 10
Các trung tuyến và

thông kê thứ tự 215
Các tiểu và Cực đại 215
Lựa chọn thời gian tuyến tính dự trù 217
Lựa chọn thời tuyến tính ca (trường hợp)
4.19 xấu nhất 220

200


8 Mục Lục

4.20

Phần IIỈ Các cấu trúc dữ liệu
4.21 C 4.22
4.23
Các cấu trúc dữ liệu cơ bản 230
hương
4.24 11 4.25
4.26 11.1 Cấc ngăn xếp và các hàng đợi 230
112
Cắc danh sách nốì kết 234
113
Thực thi các biến trỏ và các đối tượng 240
4.27
11.4 Biểu diễn các cây có gốc 245
4.28 C 4.29
hương 12

4.33 C 4.34

hương 13

4.31
122
123
4.32
4.36
132
133

4.30
Các bảng ánh số' 251
12.1 Các bảng địa chỉ trực tiếp 25 7
Các bảng ánh số 254
Các hàm ánh số
259
12.4
Định địa chỉ mở
4.35
Các cây tìm nhị phân 278
13.1 Cây tìm nhị phân là gì? 278
Truy vấn một cây tìm nhị phân 281
Chèn và xóa 28'

266

4.37 4.38

4.39 13.4 Các cây tìm nhị phan được
4.40 xây dựng ngẫu nhiên 289

4.41 C 4.42
4.43
Các cây đỏ đen 299
hương 14
4.44
14.1
Các tính chất của cây đỏ
đen 299
142
Các phép quay 302
143
Phép chen 304
14.4
309cường các cấu trúc dữ liệu 319
4.46 C 4.47 4.45
4.48Phép xóa
Tăng
hươhg 15
4.49 15.1 Thống kê thứ tự động 319
152
Cách tăng cường một cấu trúc dữ liệu 325
153
Các cây quãng 329
4.50



4.51

Phần IV Các kỹ,thuật phân tích và thiết kế cao cấp

4.52

4.53
4.54 Mở đẩu 337

4.55 Chươn 4.56 1
g 16
6.1
4.59
4.60 1
62
4.63 1
4.654.62
63

4.57 Lập trình động 339
4.58 Phép nhân xích ma trận 340
4.61 Các thành phần của lập trình động 348
4.64 Dãy con chung dài nhất 354


Mục Lục

9

16.4
Chương 17 17.1 172
173
★ 17.4
175

Chương 18 18.1 182
183
18.4

4.79

4.66

Phép tam giác phân đa giác lối ưu 359

4.67
4.68
4.69
4.70
4.71
4.73

Các thuật toán tham 369
Một bài toán lựa chọn hoạt động 369
Các thành phần của chiến lược tham 373
Các mã Huffman 378
Nền tảng lý thuyết cho các
4.72 phương pháp tham 386
Bài toán lên lịch cơng việc 393

4.74
4.75
4.76
4.77
4.78


Phân tích khâu trừ 399
Phương pháp kết tập 400
Phương pháp kế toán 404
Phương pháp thế 407
Các bảng động 411

Phần V Các cấu trúc dữ liệu cao cấp

4.80
Mở đầu 426
4.81 C 4.82 4.83 1 4.86 Các cây B 428
hương 19 9.1
4.87 Định nghĩa cây B 432
4.90
4.84 1 4.88 Các phép tốn (ịơ bản trên các cây B 434
4.89 Xóa một khóa ra khỏi một cây B 443
92
4.85 1
4.91 C 4.92 4.93 2 4.95 Các đông nhị thức 449
4.98
hương 20 0.1
450
4.96 Các cây nhị thức và các đống nhị
4.94 2 thức
4.99
02
4.97 Các phép toán trên các đống nhị thức 455
4.111
4.100 C 4.101 4.1022 4.106

Các đông
hương 21 1.1
Fibonacci
471
4.1032 4.107Cấu trúc của các đống Fibonacci 472
12
4.108Các phép toán đống khả trộn 475
4.1042 4.109Giảm một khóa và xóa một mắt 484
13
4.110 Định cận độ cực đại 488
4.116
4.112 C 4.113 4.1144.115 Các cấu trúc dữ liệu cho các
hương 22
4.117 4.118
4.122 tập hợp rờỉ nhau 493
4.119 2 4.123Các phép toán tập hợp rời 493
2.1
4.124Phần biểu diễn danh sách nối kết
4.1202
4.125 của các tập hợp rời 4.127
22
4.126Các
rừng
tập
hợp rời 500
496
4.128


10 Mục Lục


4.129 ★

22.4 Phân tích heuristic hợp theo hạng
4.130 với nén lộ trình 504

4.131 VI Thuật tốn đồ thị

Chương 23
23.1
232
233
23.4
235
Chương 24
24.1
242
Chương 25

4.132

Mở đầu 519

4.133
4.134
4.135
4.136
4.137
544
4.138


Các thuật toán đồ thị căn bản 527
Các phép biểu diễn của đồ thị 52 ỉ
Tìm kiếm độ rộng đầu tiên 525
Tìm kiếm độ sâu đầu tiên 534
Phân tích lợp theo hạng với nén lộ trình

4.139
4.140
559
4.141

Các cây tỏa nhánh tối thiểu 55Ẩ
Tãng trưỏng một cây tỏa nhánh cực tiểu

Các thành phần liên thơng mạnh 547

Thuật tốn Kruskal và Prim 564
25.1
4.142
Các lộ trình ngắn nhất nguồn đơn 574
252
4.143
Các lộ trình ngắn nhất và phép nới lỏng
253
25.4 579
4.144
Thuật tốn Dijkstra 588
4.145
Thuật tốn Bellman-Ford 594

255
4.146
Các lộ trình ngắn nhất nguồn đơn trong đồ
thị phi chu trình có hướng 598 Cấc hạn chế sai phân
và các lộ trình ngắn nhất 601
26.1
4.147
Các lộ trình ngắn nhâ't mọi cặp 614

Chương 26

262
263
26.4

4.148

4.149

Chương 27

*

27.1
272
273
27.4
275

4.150

4.151

Các lộ trình ngắn nhất
và phép nhân ma trận
616
Thuật tốn FloydWarshall 623
Thuật toán Johnson
cho đồ thị thưa 630
Một khung sườn
chung để giải quyết
635


Mục Lục

4.152
4.153
4.154
4.155
4.156
4.157

11

Luồng cực đại 645
Cắc mạng luồng 646
Phương pháp Ford-Fulkerson 655
So khớp hai nhánh cực đại 668
Các thuật toán đẩy luồng trước 6 73
Thuật toán nâng tới trước 685



12 Mục Lục

4.158

Phần Vĩĩ Các chả đề chọn lọc
4.159 Mở đầu 703

4.160

Các mạng sắp xếp 706
4.161
Chương 28
4.162
28.1
4.163
282
4.164
283
4.165
28.4
285
4.166
Chương 29
29.1
29.2
293
29.4


4.171
song 766
30.1
4.172
302
4.173

Chươhg 30

303



30.4

4.175
4.176

305

4.178

31.1
312

4.179
4.180
4.181

313


4.183

Chương 31



Chương 32

4.167
4.168
4.169
4.170

Các mạng so sánh 706
Nguyên iý Zero - một 71 ì
Mạng sắp xếp bitonic 7Ỉ5
Một mạng trộn 7Ỉ9
Mạng sắp xếp 72ỉ
Các mạch sô' học 728
Các mạch tổ hợp 729
Các mạch cộng 735
Các mạch nhân 747
Các mạch gắn đồng hồ 754
Các thuật tốn cho các máy tính song
Nhảy biến trỏ 770
Các thuật toán CRCW và các
4.174 thuật toán EREW 78Ỉ
Định ỉý Brent và tính hiệu quả cơng 79Ĩ
Phép tính tiền lơ song song

4.177
hiệu quả cơng 795
Ngắt tính đối xứng tất định 802
Các phép tốn ma trận
813
Các tính chất của các ma trận 813
Thuật toán Strassen với phép nhân
4.182 ma trận 823
Các hệ thống số đại sô' và
4.184 phép nhân ma trận bool 830
Giải các hệ thống phương trình tuyến tính

314
4.185
315 835
31.6
4.186
Đảo các ma trận 849
4.187
Các ma trận xác định dương đối xứng và
phép xấp xỉ các bình phương bé nhất 854
32.1
4.188
Các đa thức và FFT 865
322
4.189
Phần biểu diễn của các đa thức 867


Mục Lục


4.190

DFTvaFFT 873

13


14 Mục Lục

4.191

323 Cấc thực thi FFT hiệu quả 88ỉ
Chương 33 Các thuật toán lý thuyết S(Y 890
33.1
Các khái niệm lý thuyết số cơ bản 891
33.2
Ước sô' chung lờn nhất 898
4.192 333 Số học moduỉa 904
33.4
Giải các phương trình tuyến lính modula 910
4.193 335 Định lý phần dư Tàu 914
33.6
Các lũy thừa của một thành phần 918
33.7
Hê mật mã khóa cơng RSA 922
4.194 3318 Thử tính ngun 929
4.195 ★
33.9 Phép thừa số hóa sơ' ngun 938
34 So khởp chuỗi 948

34.1
Thuật toán so khớp chuỗi đơn sơ 950
Thuật toán Rabin-Karp 953
So khớp chuỗi với otomat hữu hạn 959
Thuật toán Knuth-Morris-Pratt 966
345 Thuật tốn Boyer-Moore 974

Chương
342
343
34.4
4.196 'k

35 Hình học điện tốn 984
35.1
Các tính chất đoạn thẳng 985
352 Xác định bất một cặp bất kỳ có
4.197
giao nhau khơng 990
Tìm bao lồi 997
Tìm cặp điểm sát nhất 1009

Chương

353
35.4

36 Tính đẩy đủ NP 1018
Chương
36.1

Thời gian đa thức 1019
362 Xác minh thời gian đa thức 1028
363

364
365

Lời tựa
Chương

366
Giáo trình Thuật tốn—Lý thuyết và bài tập Sơ cấp - Trung cấp - Cao
cấp là tập sách giới thiệu tồn diện cơng trình nghiên cứu hiện đại về các thuật
tốn máy tính. Khơng nhừng trình bày nhiều thuật tốn và đề cập khá chun sâu,
nó cịn mơ ta cách thiết kế và phân tích chúng sao cho mọi tầng lớp độc giá đều có


Mục Lục

15

thể tiếp thu. Chúng tôi gắng giữ phần giải thích CF mức cãn bân song vẫn khơng
để mâì tính chun sâu hoặc độ chính xác tốn học.
367 Mỗi chương trình bày một thuật tốn, một kỹ thuật thiết kế, một lĩnh vực
ứng dụng, hoặc một chủ đề liên quan. Các thuật tốn được mơ ta bằng tiêng Anh
và một "mà giả“ Ipseudocodeị được thiết kế để những ai đã từng biết chút ít về lập
trình đều có thể đọc dược. Cuốn sách chứa đựng trên 260 hình, minh họa cách làm
việc của các thuật tốn. Do tính hiệu CỊUCỈ là một trong những quy chuẩn thiết kế
của sách, nên chúng tơi đã tiên hành phân tích cẩn thận các góc độ thời gian thực
hiện của tất ca các thuật toan.

368 Nội dung của sách chủ yếu được dùng cho các khóa học năm cl cao
đẳng/dại học và sau dại học về thuật toán hoặc cấu trúc dừ liệu. Do nó đề cập các
vân đề thiết kế kỹ thuật [engineeringl trong thiết kê thuật toán, cũng như các lỉnh
vực toán học, nên cùng thích hợp với các chuyên viên kỹ thuật muôn tự học.
369
Với thầy giáo
370
Cuốn sách này được thiết kế vừa linh hoạt vừa tồn diện. Nó sẽ hữu ích
đối với bạn trong nhiều khóa học khác nhau, từ khóa học năm cuổì về các câu trúc
dữ liệu cho đến khóa học sau đại học về các thuật tốn. Do nội dung chuyển tải
nhiều hơn đáng kể so với một đơn vị học trình thơng thường, nên bạn có thể xem
cuốn sách như một “tủ chén bút ” hoặc “quầy thức ãn dọn sần” mà bạn có thể lựa
chọn chất liệu thích hợp nhất hỗ trợ cho khóa học sè dạy.
371 Bạn có thể thoải mái tổ chức khóa học dựa trên chỉ những chương cần
thiết. Các chương ở đây được thiết kế tương đối độc lập nhau, do đó bạn khơng
cần bận tâm về khả nũng lệ thuộc bất ngờ và không cần thiết giữa các chương.
Mỗi chương đều đề cập nội dung theo trình tự dễ trươc khó sau, có các điểm
ngừng tự nhiên đánh dâii ranh giói mỗi đoạn. Trong khóa học cuối cap, bạn có thể
chỉ dùng các đoạn đầu của một chương; trong các khóa cao học, bạn có thể đề cập
nguyên ca chương.
372
Tập sách có gộp trên 900 bài tập và 120 bài toán. Mỗi đoạn kêt thúc bằng
các bài tập, và mỗi chương kết thúc bằng các bài tốn. Nói chung, các bài tập là
những câu hỏi ngắn trắc nghiệm mức tiêp thu cũn ban về nội dung. Một số là bùi tập
tư duy tự kiểm tra đơn giân. trong khi một số khác lại thích hợp để ra bài tập ở nhà.
Các bài toan là những điển cứu lease studies) công phu hơn, thường giới thiệu nội
dung mơi: noi chung, chúng gộp một vài câu hc$i dẫn dắt sinh viên qua các bươc cần
thiêt đế đi đến một giải pháp.
373
Chúng tôi đánh dâu sao (*) các doạn và các bài tập thích hợp cho các

sinh viên cao học hơn so vơi các sinh viên cuối câp. Một đoạn cơ đíính dâu sao
khơng nhất thiết khó hơn một đoạn bình thương, song nơ cơ thể yêu cầu một trình độ
toan học cao cấp hơn. Cũng vậy. các bài tập cơ đánh dấu sao cơ thể yêu cáu một vốn
kiến thức cao câp ngồi khả năng sấng tạo trung bình.
374 Với sinh viên


16 Mục Lục

375 Hy vọng cuốn giáo trình này sẽ cung cấp cho bạn một sô' khái niệm hấp dẫn về
lĩnh vực thuật tốn. Chúng tơi đã cơ' gắng trình bày mọi thuật tốn theo góc cạnh dễ
tiếp thu và thú vị. Đề giúp bạn khi gặp các thuật toán lạ hoặc khơ, chúng được mô tả
theo từng bước một. Tập sách cùng giải thích các khái niệm tốn học cẩn thiết để
giúp bạn nắm vững tiên trình phan tích các thuật toán. Nếu đã hơi quen vơi một chủ
đề, bạn sè thây các chương được tổ chức để bạn có thể lươt nhanh cúc đoạn giơi
thiệu và nhanh chóng bắt kịp các nội dung cao cấp hơn.
376
Đây là một cuôn sách lơn, và lớp học của bạn ắt chỉ đề cạp mọt phần nội
dung của nơ. Tuy nhiên, chúng tôi đã gắng biến nơ thành một cuo'n sách hữu ích cho
bạn vơi tư cách là một cuốn giáo trình trước mắt và một tài liệu toán học hoạc một
cuốn cẩm nang thiết kế kỹ thuật luôn cơ mặt trên bàn giây để bạn tham khảo cho
nghề nghiệp của mình sau này.
377

Điều kiện tiên quyết để đọc cuốn sách này

378 • Để đạt kêt quả cao, bạn phải có một sơ' kinh nghiêm nhất định về lập
trình. Đặc biệt, bạn phải hiểu rõ các thủ tục đệ quy và các câu trúc dừ liệu đơn giản
như các mang và các danh sách nơ'i kết [linked lists).
379

• Bạn phải cơ khả nãng chứng minh bằng phép quy nạp toán học.
380này
Một
vài
phần
trong
sách
dựaPhần
vào một
sơ'
kiến
thức
căn bản
sẽ
giải
về
tính
thích
tốn.
tat cả
Ngồi
kỹ thuật
ra,
I của
cuốn
sách


Lời tựa


381

toán học mà bạn cần biết.

382

Với các chuyên gia

lữ

383
Với nhiều chủ đề đa dạng, cuốn sách này đã trở thành một cẩm nang
tuyệt vời về thuật toán. Do mỗi chương tương đối độc lập vơi nhau, nên bạn có thể
tạp trung vào các chủ đề mà bạn quan tâm nhát
384 Hẩu hết các thuật tốn mơ tâ trong sách này đều có tính tiện ích thực tiễn
cao. Do đơ, ta sẽ xét đến kha năng thực thi và các vấn đề thiết kế kỹ thuật khác.
Nói chung, tập sách sẽ mô tâ các phương án thay thế thực tiễn đối vơi mọt sơ'
thuật tốn thiên về lý thuyết.
385 Nếu muốn thực thi một thuật toán nào đơ, bạn cơ thé dễ dàng phiên dịch
mã gia của tập sách này thành ngơn ngữ lạp trình mà bạn ưa thích. Mã gia được
thiết kế để trình bày từng thuật toan thật rõ ràng vù súc tích. Kết qua là, tập sách
khơng đề cập đến tính nũng điểu quản lỗi và các vấn đề thiết kế phẩn mềm khác,
đòi hỏi phải cơ các giả thiết cụ thể về mơi trương lập trình của bạn. Chúng tơi
gắng trình bày đơn gian và trực tiếp từng thuật tốn mà khơng nêu các đặc trưng
của mọt ngơn ngừ lập trình cụ thể nào cơ the làm lu mèí điều cốt lõi của nó.
386

Cáo lỗỉ

387

Một cn sách vơi số trang dày như thế này chắc chắn khơng thể tránh
được các sai sót đáng tiếc. Chúng tơi xin thành thật mong quý bạn thông cảm và
trông đợi sự gơp ý xây dựng của quý bạn. Ngoài ra, chúng tôi cũng hân hoan đơn
nhận các gợi ý về các bài tập và các bài toán mơi, song cũng lùm ơn gộp phần dáp
án. Bạn cơ thể gửi về cho chúng tôi thông qua Nhà Xuất bản Thông Kê và xin trân
trọng cảm ơn.
390

PRESS

388
Tập thể tấc giả
389
NGỌC ANH THƯ


391
392
393
394
395
396
397
398
399
400
401
402
403


Nhập Mơn Thuật Tốn

IĨRƯỮMGĐẠI HỌC KHA i

1

THƯ VỉỆN ị

404

405
406

1 Giới Thiệu

407 Chương này giúp bạn làm quen với cơ trường hỢpu sẽ được dùng
suốt cuốn sách này để suy nghĩ về tiến trình thiết kế và phân tích các thuật
tốn. Tuy chương mang tính độc lập, song nó cũng gộp vài tham chiếu đến
cấc nội dung sẽ được giới thiệu trong Phần I.


408 Để bắt đầu, ta tìm hiểu các vấn đề tính tốn nói chung và các thuật
tốn cần thiết để giải quyết chúng, lấy bài tốn sắp xếp làm ví dụ thực tiễn.
Chương này cũng nêu một “mã giả” quen thuộc với những bạn đọc đã từng
lập trình trên máy tính để nêu cách đặc tả các thuật tốn. Sắp xếp chèn
[insertion sort], một thuật toán sắp xếp đơn giản, được dùng làm ví dụ mở
đầu. Ta sẽ phân tích thời gian thực hiện [running time] của tiến trình sắp xếp
chèn, giới thiệu một hệ ký hiệu tập trung vào cách thức mà thời gian đó tăng
lến theo số lượng các mục được sắp xếp. Ta cũng sè tìm hiểu cách tiếp cận
“chia để trị” đốì với tiến trình thiết kế các thuật tốn và dùng nó để phát triển

một thuật tốn có tên sắp xếp trộn [merge sort]. Phần cuối chương sẽ so sánh
hai thuật toán sắp xếp.

1.1 Thuật tốn
409 Nơm na, thuật tốn [algorithm] là m?t thủ tục tính tốn được định
nghĩa kỹ, sử dụng một giá trị, hoặc tập hợp các giá trị nào đó, làm đầu vào và
cho ra một giá trị, hoặc tập hợp các giá trị nào đó, làm kết xuất. Do đó, một
thuật tốn là một trình tự các bước tính tốn biến đổi đầu vào thành kết xuất.
410 Cũng có thể xem một thuật tốn như một cơng cụ để giải quyết một
bài toán thật cụ thể. Phát biểu của bài toán sè chỉ định tổng quát môi quan hệ
nhập/xuât cần thiêt. Thuật tốn mơ tả một thủ tục tính tốn cụ thể để đạt được
mối quan hệ nhập/xuất đó.
411 Để bắt đầu q trình nghiên cứu các thuật tốn, ta sử dụng bài toán
sắp xếp một dãy các con số theo thứ tự khơng giảm [nondecreasing]. Bài tốn
này thường nảy sinh trong thực tế và cũng là mảnh đất màu mỡ
412
để giới thiệu nhiều kỹ thuật thiết kế và cấc công cụ phân tích chuẩn.
Dưới đây là cách định nghĩa hình thức bài toán sắp xếp:
413 Đầu vào: Một dày n số (a|t ữ2,..„ an}.
414 Kết xì: Một phép hốn vị (sắp xếp lại) (¿7]ứ/,..., an') của dãy đầu
vào
415 sao cho a,' < a' < ... < a'.
416 i
2
ft
417 Cho một dãy đầu vào như (31,41,59, 26, 41, 58), một thuật toán sắp
xếp sẽ trả một dãy kết xuất là (26, 31,41, 41, 58, 59). Một dãy đầu vào như
vậy được gọi là một minh dụ [instance] của bài toán sắp xếp. Nói chung, một
minh dụ của một bài tốn bao gồm tất cả mọi đẩu vào (thỏa mọi hạn chế đã
đề ra trong phát biểu của bài toán) cần thiết để tính tốn một nghiêm'cho bài

tốn.
418 Sáp xếp là một phép tốn căn bản trong khoa học máy tính (nhiều
chương trình dùng nó như một bước trung gian), và kết quả là nhiều thuật
toán sắp xếp tốt đã được phát triển. Thuật tốn nào là tơi nhất đơ'i với một


ứng dụng đã cho, điều này tùy thuộc vào S(í lượng các mục sẽ được sắp xếp,
chừng mực mà các mục đó đà được sắp xếp sấn, và loại thiết bị lưu trữ được
dùng: bộ nhứ chính, các đĩa, hoặc băng từ.
419 Một thuật toán được xem là đúng đắn nếu, với mọi minh dụ đầu vào,
nó ngừng với kết xuất đúng. Ta nói rằng một thuật tốn đúng giải quyết được
bài tốn đã cho. Một thuật tốn sai có thể khơng ngưng gì cả trên vài minh dụ
đầu vào, hoặc có thể ngưng với đáp án ngồi ý muốn. Trái với dự đốn, các
thuật tốn sai đơi lúc cũng hữu ích, nếu như có thể kiểm sốt mức độ lỗi của
chúng. Ta sẽ thây một ví dụ về điều này trong Chương 33 khi nghiên cứu cấc
thuật toán để tìm các số ngun tơ' lớn. Tuy nhiên, bình thường ta chỉ quan
tâm đến các thuật toán đúng.
420 Một thuật tốn có thể được đặc tả bằng tiếng Anh, như một chương
trình máy tính, hoặc thậm chí như một thiết kế phần cứng. Yêu cầu duy nhất
đó là phần đặc tả phải mơ lả chính xác thủ tục tính tốn sẽ phải theo.
421__________________________________Tập sách này sẽ mơ tả các
thuật tốn dưói dạng các chương trình được viết bằng mã giả rất giống vđi c,
Pascal, hay Algol. Nếu đã quen với một trong số cấc ngơn ngữ này, bạn có thể
dề dàng đọc các thuật toán ở đây. Sự khấc biẹt giữa mã gia và mã “thật” đó là:
trong mã gia, ta sử dụng mọi phương pháp biểu đạt rõ ràng và súc tích nhất để
đặc lả một thuật tốn nhất định. Thĩnh thoảng, phương pháp rỏ rệt nhất là
liếng Anh, do đó khơng có gì ngạc nhiên nếu bạn gặp một câu hay cụm lừ
liếng Anh (mà trong trường hợp thuận tiện chứng tôi sè sử dụng tiêng Việt đế
quỹ bạn tiện theo dõi_______________________ND) xen lẫn trong một đoạn
mã “thật”. Một khấc biệt nữa giữa mã giả và mà thật đó là: mà giả thường

khơng dính dáng đến các vấn đề về thiêt kê kỹ thuật phần mềm. Các vân đề
như trừu tượng hóa dữ liệu, tính mơđun, và điều quản lỗi thường được bỏ qua
để chuyển tai chính xác hơn nội dung cốt lõi của thuật toán.
422Sắp xếp chèn
423
Trước tiên, ta tìm hiểu phương pháp sắp xếp chèn [inscrtion sort],
đây là một thuật toán hiệu quả để sắp xếp các thành phần có số lượng nhỏ. Kỹ
thuật sắp xếp chèn làm việc giông như cách thức mà nhiều người xếp một tay
bài tây hay bài rumi. Ta bắt đầu bằng một tay trái trắng với các lá bài tung sấp
trên bàn. Sau đó, lần lượt dỡ từng lá bài một ra khỏi bàn rồi chèn nó vào đúng vị
trí trong tay trái. Để tìm đúng vị trí cho một lá bài, ta so sánh nó với mỗi lá bài
sấn có trong tay, từ phải qua trái, như minh họa trong Hình 1.1.


424
425
426

Hình 1.1 Xêp một tay bài theo phương pháp sắp xếp chèn.

427
Mã giả sắp xêp chèn của chúng ta được trình bày dưới dạng một thủ
tục tên INSERTION-SORT, nó nhận một mảng A| 1../?] dưới dạng một tham số,
chứa một dãy có chiều dài n sẻ được sắp xếp. (Trong mà, sô n thành phần trong
A được biểu thị bằng lengíhịAị.) Cúc con sơ'nhập được săp xếp tại chơ: các con
số được dàn xếp lại trong mảng A, ln có tơi đa một số lượng bâì biến của
chúng được lưu trữ ngoài mảng. Mảng dầu vào A chứa dày kết xuất đã sắp xốp
khi INSERTỈON-SORT hoànkt.
428


INSERTION-SORT(A)

1 for ị <— 2 to Ịengĩh[A]
2

do key
3

>?' chèn A[/l vào chuỗi có sắp xếp A[ 1 ..j -1 ].

4

ỉ <^j- 1

5

while ì > 0 và A[i] > key

429
430
431

6d[í +1] ^A[z]
7

ì <- i - 1

8 Â[Z +i] <— key


432 Hình 1.2 nêu cách làm việc của thuật toán này với A = <5, 2, 4, 6, 1,
3>. Chỉ số j nêu rõ “lá bài hiện hành” đang được chèn vào tay. Các thành phần
mảng A[l.j - 1] tạo thành tay đang được sắp xếp, và các thành phần A[ị + l..n]
tương ứng với đơng lá bài vẫn cịn trên bàn. Chỉ sơ' j dời từ trái sang phải qua
mảng. Với mỗi lần lặp của vịng lặp for “phía ngồi”, thành phần Â[/] được lấy
ra khỏi mảng (dịng 2). Sau đó, bắt đầu tại vị trí j - 1, các thành phần liến tiếp
được dời về bên phải một vị trí cho đến khi tìm thấy vị trí đúng đắn cho A[/]
(cấc dịng 4-7), tại điểm mà nó được chèn (dịng 8).


433
434
435 1

2

3

4

5

6 done

436
Hình 1.2 Phép tốn INSERTION-SORT trên mảng A = <5, 2, 4, 6, 1, 3)>.
VỊ trí của chỉ số j được nêu rõ bởi một vòng tròn.
437

Các quy ước mã giả


438

Tập sách này sử dụng các quy ước dưới đây trong mà giả.

1.
Thụt đầu dòng để nêu rõ cấu trúc khơi. Ví dụ, thân của vịng lặp for
bắt đầu trên dòng 1 bao gồm các dòng 2’8, và thân của vòng lặp while bắt đầu trên
dòng 5 chứa các dịng 6-7 nhưng khơng có dịng 8. Kiểu thụt dòng của chúng ta
cũng áp dụng cho các câu lệnh if-then- else. Dùng kiểu thụt dịng thay vì các dâu
chỉ quy ước của câu trúc khôi, như các câu lệnh begin và end, sẽ tránh được sự bừa
bộn trong khi vẫn bảo tồn, thậm chí cịn tăng cường, tính mình bạch1.
2. Các kiến tạo vòng lặp while, for, và repeat và các kiến tạo điều kiện if, then,
và else cũng được diễn dịch giống như trong Pascal.
3. Ký hiệu nêu rõ phần còn lại của dòng là một chú giải.
4. Kiểu nhiều phép gán theo dạng i <— j <- e sẽ gán cho cả hai biến i và j giá
trị của biểu thức e; nó sẽ được xem như tương đương với phép gán j <— e
theo sau là phép gán i J.
5. Các biến (như 4 j, và key) là cục bộ đối vđi thủ tục đã cho. Ta khơng dùng các
biến tồn cục mà khơng khai báo tường minh.
6. Các thành phần mảng được truy cập bằng cách đặc tả tên mảng theo sau là
chỉ số trong các dấu ngoặc vng. Ví dụ, A[í'] nêu rõ thành phần thứ i của
mảng A. Ký hiệu được dùng để nêu rõ một miền các giá trị trong một mảng.
Do đó, A[l..j] nêu rõ mảng con A bao gồm các thành phần A[l], A[2],..., A[jl
7. Dữ liệu phức hợp thường được tổ chức thành các đối tượng [objects], bao
hàm các thuộc tính [attributes] hoặc các trường [fields]. Để truy cập một
trường cụ thể, ta dùng tên trường theo sau là tên đối tượng của nó trong các
dấu ngoặc vng. Ví dụ, ta xem một mảng như một đối tượng có thuộc tính
length nêu rõ số lượng thành phần mà nó chứa. Để đặc tả số lượng thành
phần trong một mảng A, ta viết ỉength[AỴ Tuy ta dùng các dấu ngoặc vuông



cho cả trường hợp chỉ số mảng lẫn các thuộc tính đổì tượng, song nó vẫn rõ ý
theo từng ngữ cảnh diễn dịch.
439
Một biến biểu thị cho một
mảng hay đôi tượng sẽ được xử lý như một biên trỏ [pointer] đên dữ liệu biểu
thị cho mảng hay đốỉ tượng đó. Với tất cả trường/của một đốỉ tượng X, việc
ấn định y 3,
thì sau đó khơng những
440
là f [%] = 3, mà còn là f [y] = 3. Nói each khác, X và y trỏ đến (“là ”)
cùng đốỉ tượng sau phép gán y <— X.
441 Đôi lúc, một biên trỏ không tham chiếu một đôi tượng nào cả. Trong
trường hỢp này, ta gán cho nó giá trị đặc biệt NIL.
8. Các tham sô được chuyền cho thủ tục theo giá trị: thủ tục được gọi
442cấp
1: dịng
Trongkhó
cácxác
ngơn
ngữkhi
lập
thực
tanhiều
khơng
nên
dụngthụt
một

mình
tính
năng
định
thụt
dịng
mãtrình
để nêu
được
tách
rõ thụ,
cấu trúc
thành
khối,
trang.
bởisửcác


24 Chương 1 Giới thiệu

443
sẽ nhận bản sao các tham số riêng của nó, và nếu nó gán một giá trị
cho một tham số, thường trình gọi [calling routine] sẽ khơng thấy sự thay đổi
đó. Khi các đơi tượng được chuyền, biến trỏ đến dữ liệu biểu thị cho đối
tượng đó sẽ được chép, song các trường của đối tượng thì khơng. Ví dụ, nếu
X là một tham số của một thủ tục được gọi [called procedure], thủ tục gọi sẽ
không thấy phép gán X <— y trong thủ tục được gọi. Tuy nhiên, phép gán/
[jc] <— 3 lại lộ diện.
444 Bàỉtập
1.1- 1

445 Dùng Hình 1.2 làm mẫu, hãy minh họa phép toán của thủ tục INSERTION-SORT trên mảng A =• <31, 41, 59, 26, 41,58>.
1.1- 2
446 Viết lại thủ tục INSERTION-SORT để sắp xếp theo thứ tự không
tăng [nonincreasing] thay vì khơng giảm [nondecreasing].
1.1- 3
447 Cho bài tốn tìm kiếm:
448 Đầu vào: Một dãy n con sô" A = (aư a2,...,an) và một giá trị V.
449 Kết xuâ't: Một chỉ số ỉ sao cho V = A[z] hoặc giá trị đặc biệt NIL
nếu V không xuâ"t hiện trong A.
450 Viết mã giả cho kỹ thuật tỉm kiếm tuyến tính, qt qua dãy, tìm V.
1.1- 4
451 Xét bài tốn cộng hai số nguyên nhị phân n-bit, lưu trữ trong hai
mảng A và B /7-thành phần. Tổng hai sô" nguyên sẽ được lưu trữ theo dạng
nhị phân trong một mảng c (n+l)-thành phần. Phát biểu bài tốn theo hình
thức và viết mã giả để cộng hai số nguyên.
1.2 Phân tích các thuật tốn
452 Phân tích một thuật tốn thường hàm ý tiên liệu các tài nguyên mà
thuật toán yêu cầu. Thỉnh thoảng, các tài nguyên như bộ nhớ, bãng thông,
hoặc các cổng lôgic là những yếu tô" được quan tâm hàng đáu, song đa phần
chính thời gian tính tốn mới là yếu tố mà ta cần đo lường. Nói chung, nhờ
phân tích vài thuật tốn ứng tuyển của một bài tốn, ta có thể dễ dàng nhận ra
thuật tốn nào là hiệu quả nhâ"t. Kiểu phân tích như vậy có thể nêu rõ nhiều
ứng viên tồn tại, song một vài thuật toán kém hơn thường bị loại trong khi
tiến hành.
453 Để có thể phân tích một thuật tốn, ta phải áp dụng một mơ hình
cơng nghệ thực thi, kể cả mơ hình cho các tài ngun của cơng nghệ đó và cấc chi
phí của chúng. Đa phần tập sách này mặc nhận sử dụng mơ hình điện tốn RAM
{random-access machine ~ máy truy cập ngẫu nhiên), một bộ xử lý chung, làm



1.2 Phân tích Các Thuật tốn

25

cơng nghệ thực thi và ngầm hiểu rằng các thuật toán sẽ được thực thi dưới dạng các
chương trình máy tính. Trong mơ hình RAM, các chỉ lệnh được thi hành lần lượt,
mà khơng có các phép toán đồng thời. Tuy nhiên, trong các chương sau, ta sẽ có dịp
nghiên cứu các mo hình của các máy tính song song và phần cứng số hóa.
454 Q trình phân tích ln là một thách thức, thậm chí với một thuật
tốn đơn giản. Các cơng cụ tốn học cần thiết có thể gồm cả tốn học tổ hợp
trừu tượng, lý thuyết xác suất căn bản, kỹ năng về đại sô\ và khả năng định
danh các số hạng quan trọng nhất trong một công thức. Do cách ứng xử của
một thuật tốn có thể khác nhau đối với từng đầu vào khả dĩ, nên ta cần có
một biện phấp để tóm lược cách ứng xử thành các cơng thức đơn giản và dễ
hiểu.
455 Cho dù thông thường chỉ ỉựa mơ hình một máy để phân tích một
thuật tốn nào đó, song ta vẫn phải đối mặt với nhiều chọn lựa khi quyết định
cách diễn tả tiến trình phân tích. Một mục tiêu tức thời đó là tìm một biện
pháp diễn tả đơn giản để viết và điều tác [manipulate], nêu các đặc tính quan
trọng của các yêu cầu tài nguyên của một thuật toán, và hủy bỏ các chi tiết dài
dịng.
456

Phân tích kỹ thuật sắp xếp chèn

457 Thời gian kéo dài của thủ tục INSERTION-SORT thường tùy thuộc
vào đầu vào: tiến trình sắp xếp một ngàn con số sẽ lâu hơn tiến trình sắp xêp
ba con số. Vả lại, INSERTION-SORT có thể sử dụng các thời lượng khác
nhau để sắp xếp hai dãy đầu vào cố kích cỡ giống nhau, tùy thuộc vào mức độ
sắp xếp sấn của chúng. Nói chung, thời gian thực hiện của một thuật tốn

thường tăng theo kích cỡ đầu vào, do đố theo truyền thống, ta thường mô tả
thời gian thực hiện của một chương trình như một hàm kích cỡ đầu vào của
chương trình đó. Để thực hiện, ta cần định nghĩa các thuật ngữ “thời gian thực
hiện” [running time] và “kích cỡ đầu vào” [size of input] cẩn thận hơn.
458 Ý niệm thích hợp nhât của kích cd đầu vào thường tùy thuộc vào bài
toán đang nghiên cứu. Với nhiều bài tốn, như sắp xếp hoặc tính tốn các
phép biến đổi Fourier, số đo tự nhiên nhất đó là số lượng các mục trong đầu
vào—ví dụ, kích cỡ mảng n để sắp xếp. Với nhiều bài toán khác, như nhân hai
số ngun, sơ' đo tơi nhât của kích cỡ đầu vào lại là tổng số bit cần thiết để
biểu thị đầu vào theo hệ ký hiệu nhị phân bình thường. Đơi lúc, việc mơ tả
kích cỡ đẩu vào bằng hai con sơ' thay vì một lại tỏ ra thích hợp hơn. Ví dụ,
nếu đầu vào cho một thuật tốn là một đồ thị, kích cỡ đầu vào có thể được mơ
tả bởi cấc sô' đỉnh [vertices] và các cạnh trong đồ thị. Ta sẽ nêu rõ kiểu đo
kích cỡ đầu vào sẽ được dùng với từng bài toán mà ta nghiên cứu.


×