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

Giáo trình nghiên cứu các kiểu dữ liệu có cấu trúc.pdf

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 (975.24 KB, 202 trang )

1
GIớI THIệU MÔN HọC
Trong ngôn ngữ lậ p trì nh, dữ liệ u bao gồm hai kiể u chí nh là :
- Kiể u dữ liệ u đơn giả n: char, int, long, float, enumeration, subrange.
- Kiể u dữ liệ u có cấ u trúc : struct, array, file (kiể u dữ liệ u có kí ch thước
không đổi)...
Giá o trì nh nà y tậ p trung và o việ c nghiê n cứu cá c kiể u dữ liệ u có cấ u trúc
có kí ch thước không đổi hoặ c thay đổi trong ngôn ngữ lậ p trì nh, mô tả thông qua
ngôn ngữ C. Ngoà i ra còn giới thiệ u cá c giả i thuậ t chung quanh cá c cấ u trúc dữ
liệ u nà y như cá ch tổ chức, thực hiệ n cá c phé p toán tì m kiế m, sắ p thứ tự nội, sắp
thứ tự ngoạ i...
Điề u kiệ n để có thể tì m hiể u rõ rà ng về môn học nà y là học viê n đ biế t
cá c khá i niệ m về kỹ thuậ t lậ p trì nh trê n ngôn ngữ C. Trong phầ n mở đầ u, bà i
giả ng nà y sẽ giới thiệ u cá ch thức phâ n tí ch & thiế t kế một giả i thuậ t trước khi
tì m hiể u về cá c cấ u trúc dữ liệ u cụ thể .
Và o cuối khóa học, sinh viê n có thể :
- Phâ n tí ch độ phức tạ p của cá c chương trì nh có kí ch thước nhỏ và trung
bì nh.
- Nhậ n thức đ ược sự cầ n thiế t của việ c thiế t kế cấ u trúc dữ liệ u.
- Là m quen với cá c khá i niệ m stacks, queues, danh sá ch đặ c, danh sá ch
liê n kế t, câ y nhị phâ n, câ y nhị phâ n tì m kiế m, ....
- Hiể u đ ược nguyê n lý của việ c xâ y dựng một chương trì nh má y tí nh.
- Có thể chọn lựa việ c tổ chức dữ liệ u phù hợp và cá c giả i thuậ t xử lý dữ
liệ u có hiệ u quả trong khi xâ y dựng chương trì nh. Sinh viê n cầ n lưu ý rằ ng, tùy
và o công việ c cụ thể mà ta nê n chọn cấ u trúc dữ liệ u nà o là thí ch hợp theo hướng
tối ưu về thời gian thực hiệ n hay tối ưu về bộ nhớ.
2
Chươn g I
PHÂN Tí CH & THIếT Kế
GIảI THUậT
I. mở đầu


Hầ u hế t cá c bà i toá n đề u có nhiề u giả i thuậ t khá c nhau để giả i quyế t chúng.
Vậ y là m thế nà o chọn đ ược một giả i thuậ t tốt nhấ t ?
Việ c chọn lựa phụ thuộc và o nhiề u yế u tố như : Độ phức tạ p tí nh toá n của
giả i thuậ t, chiế m dung lượng bộ nhớ, tầ n suấ t sử dụng, tí nh đơn giả n, tốc độ thực
hiệ n...
Thông thường mục tiê u chọn lựa là :
1. Giả i thuậ t rõ rà ng, dễ hiể u, dễ m hóa và hiệ u chỉ nh.
2. Giả i thuậ t sử dụng có hiệ u quả tà i nguyê n của má y tí nh và đặ c biệ t
chạ y cà ng nhanh cà ng tốt.
Do đó khi viế t chương trì nh để chạ y một lầ n hoặ c í t chạ y thì mục tiê u 1 là
quan trọng hơn cả .
Ngược lạ i khi viế t chương trì nh để chạ y nhiề u lầ n thì phí tổn chạ y chương
trì nh có thể vượt quá phí tổn lậ p chương trì nh, nhấ t là khi phả i nhậ p nhiề u số
liệ u. Nói chung, người lậ p trì nh phả i biế t chọn lựa, viế t, đá nh giá cá c giả i thuậ t
để có được giả i thuậ t tối ưu cho bà i toá n của mì nh.
II. đánh giá thời gian chạy của chươn g t r ì n h

Thời gian chạ y của chưong trì nh phụ thuộc và o :
1. Input cho chương trì nh
2. Chấ t lượng m sinh ra của chương trì nh dị ch.
3. Trạ ng thá i và tốc độ của cá c lệ nh chạ y trê n má y.
4. Độ phức tạ p thời gian của giả i thuậ t.
Điề u 1 là chức nă ng nhậ p. Kí ch thước của input (ví dụ là n) và ta thường ký
hiệ u T(n) là đạ i lượng thời gian cầ n thiế t để giả i bà i toá n kí ch thước n.
Điề u 2, 3 thường đá nh giá khó khă n vì phụ thuộc và o phầ n mề m chương
trì nh dị ch và phầ n cứng của má y.
Điều 4 là điều mà người lậ p trì nh cầ n khả o sá t để là m tă ng tốc độ của
chương trì nh.
3
III. ký hiệu o(n) và


(n) :
Ta đá nh giá tỷ lệ phá t triể n cá c hà m T(n) qua ký hiệ u O(n).
Ta nói thời gian chạ y T(n) của chương trì nh là O(n
2
) có nghĩ a là :
c > 0 và n
0
sao cho n n
0
ta có T(n) c.n
2
.
Ví dụ
: Giả sử T(0) = 1, T(1) = 4, v v...
Tổng quá t T(n) = (n +1)
2
thì ta nói T(n) là O(n
2
) vì có thể đặ t c
1
= 4, n
0
= 1,
thì khi n 1 ta có (n +1)
2
4n
2
.
Nhưng không thể lấ y n

0
= 0 vì T(0) = 1 không nhỏ hơn c.0
2
= 0,c; giả thiế t
rằ ng n 0 và T(n) 0.
Ta nói T(n) là O(f(n)) nế u const c và n
0
sao cho T(n) c.f(n), n n
0
.
Chương trì nh chạ y với thời gian O(f(n)) ta nói nó phá t triể n tỷ lệ với f(n).
Khi nói T(n) là O(f(n)) thì f(n) là chặ n trê n của T(n).
Để nó i c h ặ n d ưới của T(n) ta dùng ký hiệ u .
Ta nói T(n) là (g(n)) nế u const c, n
0
sao cho T(n) c.g(n), n n
0
.
Ví dụ
: Để kiể m tra T(n) = n
3
+ 2n
2
là (n
3
) ta đặ t c = 1 thì T(n) c.n
3
, n
= 0, 1,... (n
o

= 0).
* Sự trá i ngược của tỷ lệ phá t triể n
:
Ta giả sử cá c chương trì nh có thể đá nh giá bằ ng cá ch so sá nh cá c hà m thời
gian của chúng với cá c hằ ng tỷ lệ không đá ng kể . Khi đó ta nói chương trì nh có
thời gian chạ y O(n
2
). Nế u chương trì nh 1 chạ y mấ t 100.n
2
thời gian (mili giâ y)
thì chương trì nh 2 chạ y mấ t 5.n
3
thời gian, thì ta có tỷ số thời gian của 2 chương
trì nh là 5.n
3
/100.n
2
= n/20, nghĩ a là khi n = 20 thì thời gian chạ y 2 chương trì nh
là bằ ng nhau, khi n < 20 thì chương trì nh 2 chạ y nhanh hơn chương trì nh 1. Do
đó khi n > 20 thì nê n dùng chương trì nh 1.
Ví dụ
: Có 4 chương trì nh có 4 độ phức tạ p khá c nhau đ ược biể u diễ n trong
bả ng dưới đây.
Thời gian
chạ y T(n)
Kí ch thước bà i toá n
tối đa cho 10
3
s
Kí ch thước bà i toá n

tối đa cho 10
4
s
Tỷ lệ tă ng về
kí ch thước
100.n 10 100 10.0 lầ n
5.n
2
14 45 3.2 lầ n
n
3/2
12 27 2.3 lầ n
2
n
10 13 1.3 lầ n
Giả sử trong 10
3
s thì 4 chương trì nh giả i cá c bà i toá n có kí ch thước tối đa
trong cột 2. Nế u có má y tốt tốc độ tă ng lê n 10 lầ n thì kí ch thước tối đa tương ứng
4
của 4 chương trì nh trì nh bà y ở cột 3. Tỉ lệ hai cột 1,2 ghi ở cột 4. Như vậ y nế u
đầu tư về tốc độ 10 lầ n thì chỉ thu lợi có 30% về kí ch thước bà i toá n nế u dùng
chương trì nh có độ phức tạ p O(2
n
).
IV. cách tí nh thời gian chạy chươn g t r ì n h
:
1. Qui tắc tổng:

Giả sử T

1
(n) và T
2
(n) là thời gian chạ y chương trì nh P
1
và P
2
tương ứng đ ược
đá nh giá là O(f(n)) và O(g(n)). Khi đó T
1
(n) + T
2
(n) sẽ là O(max(f(n),g(n)))
(chạ y xong chương trì nh P
1
thì chạ y P
2
).
Chứng minh
:
Theo đị nh nghĩ a O(f(n)) và O(g(n)) thì c
1
, n
1
, c
2
, n
2
sao cho
T

1
(n) c
1
.f(n) n n
1
; T
2
(n) c
2
.g(n) n n
2
.
Đặ t n
0
= max(n
1
, n
2
)
Nế u n n
o
thì T
1
(n) + T
2
(n) (c
1
+ c
2
).max(f(n),g(n)).

2. Qui tắc tí ch:

T
1
(n). T
2
(n) là O(f(n).g(n)).
Chứng minh
: tương tự như tổng.
Ví dụ
: Có 3 chương trì nh có thời gian chạ y tương ứng là O(n
2
), O(n
3
),
O(n.logn). Thế thì thời gian chạ y 3 chương trì nh đồng thời là O(max(n
2
, n
3
,
nlogn)) sẽ là O(n
3
).
Nói chung thời gian chạ y một d y cố đị nh cá c bước là thời gian chạ y lớn
nhấ t của một bước nào đó trong d y. Cũng có trường hợp có 2 hay nhiề u bước có
thời gian chạ y không tương xứng (không lớn hơn mà cũng không nhỏ hơn). Khi
đó qui tắ c tí nh tổng phả i đ ược tí nh trong từng trường hợp.
n
4
nế u n chẵ n

Ví dụ : f(n) =

{

n
2
nế u n lẻ
g(n) = n
2
nế u n chẵ n


{

n
3
nế u n lẽ
Thời gian chạ y là O(max(f(n),g(n))) là n
4
nế u n chẵ n và n
3
nế u n lẻ .
Nế u g(n) f(n), n n
o
, n
o
là const nà o đó thì O(f(n)+g(n)) sẽ là O(f(n)).
Ví dụ
: O(n
2

+ n) = O(n
2
)
Trước khi đ ưa ra qui tắ c chung để phâ n tí ch thời gian chạ y của chương trì nh
thì ta xé t ví dụ đơn giả n sau.
5
Ví dụ : Xé t chương trì nh Bubble dùng sắ p d y số nguyê n theo chiề u tă ng.
Procedure Bubble (var A: array [1..n] of integer);
Var i, j, temp : integer ;
Begin
1 For i := 2 to n do
2 For j := n downto i do
3 If A[j-1] > A[j] then
Begin
4 temp := A[j-1] ;
5 A[j-1] := A[j] ;
6 A[j] := temp ;
End ;
End ;
Phâ n tí ch
:
- N là số phầ n tử - kí ch thước của bà i toá n. Mỗi lệ nh gá n từ dòng 4 - > dòng
6 mấ t 3 đơn vị thời gian, theo qui tắ c tí nh tổng sẽ là O(max(1,1,1) = O(1).
- Vòng If và For lồng nhau, ta phả i xé t từ trong ra ngoà i. Đối với điề u kiệ n
sau If phả i kiể m tra O(1) thời gian. Ta không chắ c thâ n lệ nh If từ 4 - 6 có thực
hiệ n hay không. Vì xé t trong trường hợp xấ u nhấ t nê n ta giả thuyế t là cá c lệ nh từ
4 - 6 đề u có thực hiệ n. Vậ y nhóm If từ cá c lệ nh 3 -6 là m mấ t O(1) thời gian.
- Ta xé t vòng lặ p ngoà i từ 2 - 6. Nguyê n tắ c chung của vòng lặ p: thời gian
vòng lặ p là tổng thời gian mỗi lầ n lặ p trong thâ n vòng lậ p. í t nhấ t là O(1) cho
mỗi lầ n lặ p khi chỉ số tă ng. Số lầ n lặ p từ 2 - 6 là n - i +1

Vậ y theo qui tắ c tí ch : O((n - i +1), 1) là O(n -i +1).
- Ta xé t vòng ngoà i cùng chứa cá c lệ nh của chương trì nh. Lệ nh 1 là m n-1
lầ n, tốn n-1 đơn vị thời gian. Vậ y tổng thời gian chạ y của chương trì nh bị chặ n
dưới bởi 1 thời gian cố đị nh là :

=
=+
n
2i
2/)1n(*n)1in(
tức là O(n
2
)
Tuy nhiê n không có qui tắ c đầ y đủ để phâ n tí ch chương trì nh.
Nói chung thời gian chạ y của 1 lệ nh hoặ c 1 nhóm lệ nh có thể là 1 hà m của
kí ch thước cá c input hoặ c 1 hay nhiề u biế n. Nhưng chỉ có n - kí ch thước của bà i
toá n là thông số cho phé p đối với thời gian chạ y của chương trì nh.
6
3. Qui tắc tí nh thời gian chạy
a) Thời gian chạ y của mỗi lệ nh gá n, read, write có giả thiế t là O(1).
b) Thời gian chạ y của 1 d y lệ nh xá c đị nh theo qui tắ c tổng; nghĩ a là
thời gian chạ y của d y là thời gian lớn nhấ t của 1 lệ nh nà o đó trong d y lệ nh.
c) Thời gian chạ y lệ nh If là thời gian thực hiệ n lệ nh điề u kiệ n cộng với
thời gian kiể m tra điề u kiệ n.
Thời gian thực hiệ n lệ nh If có cấ u trúc If then eles là thời gian kiể m
tra điề u kiệ n cộng với thời gian lớn nhấ t của 1 trong 2 lệ nh rẽ nhá nh true và
false.
d) Thời gian thực hiệ n vòng lặ p là tổng thời gian thực hiệ n thâ n vòng lặ p
và thời gian kiể m tra kế t thúc vòng lặ p.
e) Gọi thủ tục:Nế u chương trì nh có cá c thủ tục và không có thủ tục nà o

là đệ qui thì ta có thể tí nh thời gian chạ y cùng một lúc, bắ t đầ u từ cá c thủ tục
không gọi đế n cá c thủ tục khá c. Tấ t nhiê n phả i có í t nhấ t 1 thủ tục như vậ y trong
trường hợp nà y, nế u không thì phả i có thủ tục đệ qui. Sau đó ta có thể đá nh giá
thời gian chạ y của cá c thủ tục có gọi, đế n cá c thủ tục không chứa lời gọi đ đ ược
đá nh giá . Cứ như thế ta lạ i đá nh giá thời gian chạ y của cá c thủ tục có lời gọi đế n
cá c thủ tục đ đá nh giá , nghĩ a là mỗi thủ tục đ ược đá nh giá sau khi đá nh giá hế t
cá c thủ tục mà đ ược nó gọi.
Nế u có thủ tục đệ qui thì không thể tì m đ ược thứ tự của tấ t cả cá c thủ tục
sao cho mỗi thủ tục chỉ gọi đế n cá c thủ tục đ đá nh giá . Khi đó ta phả i lậ p 1 liê n
hệ giữa mỗi thủ tục đệ qui với 1 hà m thời gian chưa biế t T(n) trong đó n là kí ch
thước của đối số của thủ tục. Lúc đó ta có thể nhậ n đ ược sự truy hồi đối với T(n),
nghĩ a là 1 phương trì nh diễ n tả T(n) qua cá c T(k) với cá c giá trị k khá c nhau.
Ví dụ
: Xé t chương trì nh đệ qui tí nh n giai thừa (n!), trong đó n là kí ch
thước của hà m nê u trê n.
Function Fact (n:integer) : LongInt ;
Begin
1 If n <= 1 then
2 Fact := 1
Else
3 Fact := n*fact (n-1)
End ;
Phâ n tí ch
:
Ta ký hiệ u T(n) là thời gian chạ y để tí nh hà m Fact(n).
Thời gian chạ y đối với cá c dòng 1, 2 là O(1) và đối với dòng 3 là O(1) +
T(n-1). Vậ y với cá c hằ ng c, d nà o đó ta có phương trì nh:
7
c + T(n-1) nế u n > 1
T(n) =

d nế u n 1
Giả i phương trì nh
:
Giả sử n > 2, ta có thể khai triể n T(n-1) trong công thức :
T(n) = 2.c + T(n-2) nế u n > 2
Sau đó ta lạ i thay T(n-2) = c + T(n-3) ta đ ược.
T(n) = 3.c + T(n-3) nế u n > 3
.....
T(n) = i.c + T(n-i) nế u n > i
Cuối cùng ta thay i = n - 1, ta đ ược
T(n) = c(n-1) + T(1) = c(n-1) + d
Kế t luậ n T(n) là O(n).
V. sự phân lớp các thuật toán
:
Như đ đ ược chú ý ở trê n, hầ u hế t cá c thuậ t toá n đề u có một tham số chí nh là
N, Thông thường đó là số lượng cá c phầ n tử dữ liệ u đ ược xử lý mà ả nh hưởng rấ t
nhiề u tới thời gian chạ y. Tham số N có thể là bậ c của 1 đa thức, kí ch thước của 1
tậ p tin đ ược sắ p xế p hay tì m kiế m, số nút trong 1 đồ thị ...Hầ u hế t tấ t cả thuậ t toá n
trong bà i giả ng nà y có thời gian chạ y tiệ m cậ n tới 1 trong cá c hà m sau :
1. Hầ u hế t tấ t cả cá c chỉ thị của các chương trì nh đề u đ ược thực hiệ n một
lầ n hay nhiề u nhấ t chỉ một và i lầ n. Nế u tấ t cả cá c chỉ thị của cùng 1 chương trì nh
có tí nh chấ t nà y thì chúng ta sẽ nói rằ ng thời gian chạ y của nó là hằ ng số. Điề u
nà y hiể n nhiê n là mục tiê u phấ n đấ u để đạ t đ ược trong việ c thiế t kế thuậ t toá n.
2. logN
Khi thời gian chạ y của chương trì nh là logarit, tức là thời gian chạ y
chương trì nh tiế n chậ m khi N lớn dầ n. Thời gian chạ y loạ i nà y xuấ t hiệ n trong
cá c chương trì nh mà giả i 1 bà i toá n lớn bằ ng cá ch chuyể n nó thà nh bà i toá n nhỏ
hơn, bằ ng cá ch cắ t bỏ kí ch thước bớt 1 hằ ng số nà o đó. Với mục đí ch của chúng
ta, thời gian chạ y có đ ược xem như nhỏ hơn 1 hằ ng số "lớn". Cơ số của logarit
là m thay đổi hằ ng số đó nhưng không nhiề u: Khi n là 1000 thì logN là 3 nế u cơ

số là 10; là 10 nế u cơ số là 2 ; khi N là 1000000, logN đ ược nhân gấp đôi. Bất cứ
khi nà o N được nhâ n gấ p đôi, logN đ ược tă ng lê n thê m một hằ ng số, nhưng logN
không đ ược nhâ n gấ p đôi tới khi N tă ng tới N
2
.
3. N
Khi thời gian chạ y của chương trì nh là tuyế n tí nh, nói chung đâ y là
trường hợp mà một số lượng nhỏ cá c xử lý đ ược là m cho mỗi phầ n tử dữ liệ u nhậ p
.

{

8
Khi N là 1.000.000 thì thời gian chạ y cũng cỡ như vậ y.
Khi N đ ược nhâ n gấ p đôi thì thời gian chạ y cũng đ ược nhâ n gấ p đôi.
Đâ y là tì nh huống tối ưu cho 1 thuậ t toá n mà phả i xử lý N dữ liệ u nhậ p (hay sản
sinh ra N dữ liệ u xuấ t).
4. NlogN
Đâ y là thời gian chạ y tă ng dầ n lê n cho cá c thuậ t toá n mà giả i 1 bà i toá n
bằ ng cá ch tá ch nó thà nh cá c bà i toá n con nhỏ hơn, kế đế n giả i quyế t chúng 1
cá ch độc lậ p và sau đó tổ hợp cá c lời giả i. Bởi vì thiế u 1 tí nh từ tốt hơn (có lẽ là
"tuyế n tí nh logarit" ?), chúng ta nói rằ ng thời gian chạ y của thuậ t toán như thế là
"NlogN".
Khi N là 1000000, NlogN có lẽ khoả ng 6 triệ u.
Khi N đ ược nhâ n gấ p đôi, thời gian chạ y bị nhâ n lê n nhiề u hơn gấ p đôi
(nhưng không nhiề u lắ m).
5. N
2

Khi thời gian chạ y của 1 thuậ t toá n là bậc hai, trường hợp nà y chỉ có ý

nghĩ a thực tế cho cá c bà i toá n tương đối nhỏ. Thời gian bì nh phương thường tă ng
lê n trong cá c thuậ t toá n mà xử lý tấ t cả cá c cặp phầ n tử dữ liệ u (có thể là 2 vòng
lặ p lồng nhau).
Khi N là 1000 thì thời gian chạ y là 1000000.
Khi N đ ược nhâ n đôi thì thời gian chạ y tă ng lê n gấ p 4 lầ n.
6. N
3

Tương tự, một thuậ t toá n mà xử lý một bộ 3 của cá c phầ n tử dữ liệ u (có
lẽ 3 vòng lặ p lồng nhau) có thời gian chạ y bậ c 3 và cũng chỉ có ý nghĩ a thực tế
trong cá c bà i toá n nhỏ.
Khi N là 100 thì thời gian chạ y là 1.000.000.
Khi N đ ược nhâ n đôi thì thời gian chạ y tă ng lê n gấ p 8 lầ n.
7. 2
n

Một số í t thuậ t toá n có thời gian chạ y lũy thừa lạ i thí ch hợp trong 1 số
trường hợp thực tế , mặ c dù cá c thuậ t toá n như thế là "sự é p buộc thô bạ o" để giả i
bà i toá n.
Khi N là 20 thì thời gian chạ y xấ p xỉ là 1.000.000
Khi N là gấ p 2 thì thời gian chạ y đ ược nâ ng lê n lũy thừa 2.
Thời gian chạ y của 1 chương trì nh cụ thể đôi khi là một hằ ng số nhâ n
với cá c số hạ ng nói trê n cộng thê m một số hạ ng nhỏ hơn. Cá c giá trị của hằng số
và cá c số hạ ng phụ thuộc và o cá c kế t quả của sự phâ n tí ch và cá c chi tiế t cà i đặ t.
Hệ số của hằ ng số liê n quan tới số chỉ thị bê n trong vòng lặ p : ở 1 tầ ng tùy ý của
9
thiế t kế thuậ t toá n thì phả i cẩ n thậ n giới hạ n số chỉ thị như thế . Với N lớn thì cá c
hằ ng số đóng vai trò chủ chốt, với N nhỏ thì cá c số hạ ng cùng đóng góp và o và
sự so sá nh thuậ t toá n sẽ khó khă n hơn. Ngoà i những hà m vừa nói trê n cũng còn
có 1 số hà m khá c, ví dụ như 1 thuậ t toá n với N

2
phầ n tử dữ liệ u nhậ p mà có thời
gian chạ y là bậ c 3 theo N thì sẽ đ ược phâ n lớp như 1 thuậ t toá n N
3/2
. Một số
thuậ t toá n có 2 giai đoạ n phâ n tá ch thà nh cá c bà i toá n con và có thời gian chạ y
xấ p xỉ với Nlog
2
N.
VI. các công thức truy hồi cơ sở
:
Phầ n lớn cá c thuậ t toá n đề u dựa trê n việ c phâ n r đệ qui một bà i toá n lớn
thà nh cá c bà i toá n nhỏ hơn, rồi dùng cá c lời giả i của cá c bà i toá n nhỏ để giả i bà i
toá n ban đầ u. Thời gian chạ y của cá c thuậ t toá n như thế đ ược xá c đị nh bởi kí ch
thướ c và số lượng cá c bà i toá n con và giá phả i trả của sự phâ n r . Trong phầ n
nà y ta quan sá t cá c phương phá p cơ sở để phâ n tí ch cá c thuậ t toá n như thế và
trì nh bà y một và i công thức chuẩ n thường đ ược á p dụng trong việ c phâ n tí ch
nhiề u thuậ t toá n.
Tí nh chấ t rấ t tự nhiê n của 1 chương trì nh đệ qui là thời gian chạ y cho dữ
liệ u nhậ p có kí ch thước N sẽ phụ thuộc và o thời gian chạ y cho cá c dữ liệ u nhậ p
có kí ch thước nhỏ hơn : điề u nà y đ ược diễ n dị ch thà nh 1 công thức toá n học gọi
là quan hệ truy hồi. Cá c công thức như thế mô tả chí nh xá c tí nh nă ng của cá c
thuậ t toá n tương ứng, do đó để có đ ược thời gian chạ y chúng ta phả i giả i cá c bà i
toá n truy hồi. Bâ y giờ chúng ta chú ý và o cá c công thức chứ không phả i cá c
thuậ t toá n.
Công thức 1
:
Công thức nà y thường dùng cho cá c chương trì nh đệ qui mà có vòng lặ p
duyệ t qua dữ liệ u nhậ p để bỏ bớt 1 phầ n tử.
C

n
= C
n-1
+ n, với n >= 2 và C
1
= 1
Chứng minh
:
C
n
khoả ng n
2
/2. Để giả i 1 công thức truy hồi như trê n, chúng ta lầ n lượt áp
dụng chí nh công thức đó như sau :
C
n
= C
n-1
+ n
= C
n-2
+ (n-1) + n
= ...
= C
1
+ 2 + ... + (n-2) + (n-1) + n
= 1 + 2 + ... + n
= n(n+1)/2
10
Công thức 2 :

Công thức nà y dùng cho chương trì nh đệ qui mà chia dữ liệ u nhậ p thà nh 2
phầ n trong mỗi bước.
C
n
= C
n/2
+ 1, với n >= 2 và C
1
= 0
Chứng minh
:
C
n
khoả ng logn. Phương trì nh nà y vô nghĩ a trừ phi n chẵ n hay chúng ta giả
sử rằ ng n/2 là phé p chia nguyê n : bâ y giờ chúng ta giả sử rằ ng n = 2
m
để cho
công thức luôn luôn có nghĩ a. Chúng ta viế t như sau :
1
22
1
+=

CC
mm

2
2
2
+=


C
m

3
2
3
+=

C
m

= ......
m
C
mm
+=

2

nm log
==

Công thức chí nh xá c cho n tổng quá t thì phụ thuộc và o biể u diễ n nhị phâ n
của n, nói chung C
n
khoả ng logn với mọi n.
Công thức 3
:
Công thức nà y dùng cho chương trì nh đệ qui mà chia đôi dữ liệ u nhậ p

nhưng có thể kiể m tra mỗi phầ n tử của dữ liệ u nhậ p.
C
n
= C
n/2
+ n, với n >= 2 và C
1
= 0
Chứng minh
:
C
n
khoả ng 2n. Tương tự trê n, công thức nà y chí nh là tổng n + n/2 + n/4 + ...
(dĩ nhiê n điề u nà y chỉ chí nh xá c khi n là lũy thừa của 2).
Nế u d y là vô hạ n, thì đâ y là 1 chuỗi hì nh học đơn giả n mà đ ược ước lượng
chí nh xá c là 2n. Trong trường hợp tổng quá t lời giả i chí nh xá c phụ thuộc và o
biể u diễ n nhị phâ n của n.
Công thức 4
:
Công thức nà y dùng cho chương trì nh đệ qui mà duyệ t tuyế n tí nh xuyê n
qua dữ liệ u nhậ p, trước, trong, hay sau khi dữ liệ u nhậ p đ ược chia đôi.
C
n
= 2C
n/2
+ n, với n >= 2 và C
1
= 0
Chứng minh
:

C
n
khoả ng nlogn. Công thức nà y á p dụng cho nhiề u thuậ t toá n theo phương
phá p "chia đ ể trị ".
11
2
22
1
m
mm
CC
+=


1
22
1
1
22
+=


m
m
m
m
CC

11
2

2
2
2
++=


m
m
C

m
C
mm
mm
+=


2
2

mm
C
=+=
2
0


nn
mC
m

n
log
2
==

Lời giả i cho công thức nà y rấ t giống như trong công thức 2, nhưng phả i
chia 2 vế của công thức cho 2
n
trong bước thứ hai.
Công thức 5
:
Công thức nà y dùng cho chương trì nh đệ qui mà tách dữ liệ u thà nh 2 phầ n.
C
n
= 2C
n/2
+ 1, với n >= 2 và C
1
= 0
Chứng minh
:
C
n
khoả ng 2n. Chứng minh giống như công thức 4.
Cá c biế n dạ ng của những công thức nà y chẳ ng hạ n như điề u kiệ n khá c nhau
hay cá c số hạ ng thê m và o khá c nhau một í t, có thể ước lượng bằ ng cá ch dùng
cũng một kỹ thuậ t như trê n. Mặ c dù vậ y, chúng ta cũng nê n chú ý 1 quan hệ truy
hồi dường như tương tự với một quan hệ đ biế t thì đôi khi lạ i khó giả i hơn rấ t
nhiề u.
VII. giải phương trì nh truy hồi

:
Để giả i phương trì nh truy hồi có nhiề u cá ch giả i khá c nhau, ở đâ y chúng tôi
trì nh bà y cá ch giả i phương trì nh truy hồi bằ ng cá ch truy về phương trì nh đặ c
trưng. Chúng tôi dùng cá ch giả i nà y để viế t chương trì nh giả i tự động phương
trì nh truy hồi.
a) Ta xé t phương trì nh truy hồi thuầ n nhấ t tuyế n tí nh với cá c hệ số không
đổi sau đây :
a
0
t
n
+ a
1
t
n-1
+ ... + a
k
t
n-k
= 0 (VII.1)
trong đó t
i
(i=n, n-1,..., n-k) là cá c ẩ n số cầ n tì m.
Tuyế n tí nh vì cá c t
i
chỉ có bậ c nhấ t, thuầ n nhấ t vì vế phả i bằ ng không và
cá c hệ số a
0
, a
1

,..., a
k
là không đổi vì không phụ thuộc và o n.
12
Sau khi giả thiế t t
n
= x
n
ta đ ưa (VII.1) về dạ ng:
a
0
x
n
+ a
1
x
n-1
+...+ a
k
x
n-k
= 0
hay x
n-k
(a
0
x
k
+ a
1

x
k-1
+...+ a
k
) = 0
Rõ rà ng x = 0 là nghiệ m hiể n nhiê n, nhưng ta quan tâ m nghiệ m phương
trì nh a
0
x
k
+ a
1
x
k-1
+...+ a
k
= 0 (VII.2) và đâ y chí nh là phương trì nh đặ c trưng bậ c
k của phương trì nh truy hồi (VII.1)
Giả sử r
1
, r
2
,..., r
k
là k nghiệ m của phương trì nh (VII.2) và chúng khá c nhau
(có thể phức). Dễ dà ng kiể m tra:
r
ct
n
i

k
i
in

=
=
1

Với c
1
, c
2
,..., c
k
là cá c hằ ng xá c đị nh từ k điề u kiệ n ban đầ u.
Ví dụ 1
:
Xé t phương trì nh truy hồi:

0
43
21
=

ttt
nnn

Điề u kiệ n ban đầ u : t
0
= 1 ; t

1
=1
Phương trì nh đặ c trưng tương ứng của nó là :
x
2
- 3x - 4 = 0
có nghiệ m bằ ng -1 và 4. Vậ y nghiệ m tổng quá t là :

)4()1(
21
nn
n
cct
+=


Theo điề u kiệ n ban đầ u (khi n =0 và n = 1) ta có :
c
1
+ c
2
= 1 = t
0
- c
1
+ 4c
2
=1
Vậ y c
1

= 3/5, c
2
= 2/5. Ta được t
n
= - [4
n
- (-1)
n
] /5
Ví dụ 2
: (phương trì nh Fibonacci)
t
n
= t
n-1
+ t
n-2
n 2
Điều kiện : t
0
= 0, t
1
= 1
Viế t lạ i phương trì nh trê n :
t
n
- t
n-1
- t
n -2

= 0
Phương trì nh đặ c trưng tương ứng :
x
2
- x -1 = 0
13
Nghiệ m :
2/)51(
r
1
+=
,
2/)51(
r
2
=

Nghiệ m tổng quá t : t
n
= c
1
r
1
n

+ c
2
r
2
n


Từ điề u kiệ n ban đầ u :
c
1
+ c
2
= 0 (n = 0)
r
1
c
1
+ r
2
c
2
= 1 (n =1)
Ta có
5/1
c
1
=
,

5/1
c
2
=

Vậ y: t
n

=
5/)nn(
rr
21


Giả sử cá c nghiệ m phương trì nh đặ c trưng là không phâ n biệ t, P(x) là 1 đa
thức.
P(x) = a
0
x
k
+ a
1
x
k-1
+ ... + a
k

và r là nghiệ m ké p.
Với mỗi r > k, ta xé t đa thức bậ c n đ ược xá c đị nh như sau :
h(x) = x [x
n-k
P(x)] = a
0
nx
n
+ a
1
(n-1)x

n-1
+ ... + a
k
(n-k)x
n-k

Đặ t q(x) là đa thức thỏa điề u kiệ n
P(x) = (x-r)
2
q(x)
Ta có :
h(x) = x[(x-r)
2
x
n-k
q(x)] = x[2(x-r)x
n-k
q(x) + (x-r)
2
[x
n-k
q(x)]]
Rõ rà ng h(r) = 0, do đó
a
0
nr
n
+ a
1
(n-1)x

n-1
+ ... + a
k
(n-k) r
n-k
= 0
Nghĩ a là t
n
= nr
n
cũng là nghiệ m của (5.13). Tổng quá t hơn, nế u nghiệ m r
trùng nhau m lầ n (r bội m) thì
t
n
= r
n
, t
n
= nr
n
, t
n
= n
2
r
n
,...., t
n
= n
m-1

r
n

cũng là cá c nghiệ m của (5.13). Nghiệ m tổng quá t (nghiệ m chung) là tổ hợp
tuyế n tí nh của cá c nghiệ m riê ng nà y và nghiệ m riê ng khá c của phương trì nh đặ c
trưng. K hằ ng đ ược xá c đị nh từ cá c điề u kiệ n ban đầ u.
Ví dụ 3
: Xé t phương trì nh
t
n
= 5t
n-1
- 8t
n-2
+ 4t
n-3
n 3
với cá c điề u kiệ n t
0
= 0, t
1
= 1, t
2
= 2
Ta viế t lạ i phương trì nh:
t
n
- 5t
n-1
+ 8t

n-2
- 4t
n-3
= 0
và phương trì nh đặ c trưng tương ứng là :
x
3
- 5x
2
+ 8x - 4 = 0
hay (x-1) (x-2)
2
= 0
14
Ta có cá c nghiệ m 1 (có bội 1), 2 (có bội 2). Vậ y nghiệ m tổng quá t là :
t
n
= c
1
1
n
+ c
2
2
n
+ c
3
n2
n


Cá c điề u kiệ n ban đầ u cho trước là :
c
1
+ c
2
= 0 khi n = 0
c
1
+ 2c
2
+ 2c
3
= 1 khi n = 1
c
1
+ 4c
2
+ 8c
3
= 2 khi n = 2
Từ đâ y ta tì m ra c
1
= -2, c
2
= 2, c
3
= -1/2. Vậ y t
n
= 2
n+1

- n2
n-1
- 2
b) Phương trì nh truy hồi không thuầ n nhấ t:

Ta xé t phư ơng trì nh có dạ ng sau :
a
0
t
n
+ a
1
t
n-1
+ ... + a
k
t
n-k
= b
n
P(n) (VII.3)
Trong đó vế trá i như trong (VII.1), vế phả i là b
n
P(n) với b là hằ ng và P(n) là
đa thức.
Ví dụ 4
:
t
n
- 2t

n-1
= 3
n

thì b = 3 và P(n) = 1 là đa thức bậ c 0.
Bằ ng phé p biế n đổi đơn giả n ta có thể chuyể n ví dụ này về dạ ng (VII.1) là
phương trì nh truy hồi thuầ n nhấ t. Trước hế t ta nhâ n 2 vế cho 3 ta đ ược :
3t
n
- 6t
n-1
= 3
n+1
(1)
Sau đó ta thay n ra n + 1 trong phương trì nh ban đầ u:
t
n+1
- 2t
n
= 3
n+1
(2)
Cuối cùng, lấ y (2) - (1) , ta thu đ ược (có cùng vế phả i 3
n+1
), ta đ ược:
t
n+1
- 5t
n
+ 6t

n-1
= 0
Đế n đâ y ta có thể giả i phương trì nh đ trì nh bà y ở mục a.
Phương trì nh đặ c trưng của nó là :
x
2
- 5x + 6 = 0
hay (x-2) (x-3) = 0
Trực giá c cho ta thấ y rằ ng thà nh phầ n (x-2) tương ứng với vế trá i
phương trì nh ban đầ u; còn (x-3) là biể u hiệ n kế t quả của việ c biến đổi và trừ vế
phả i.
Ví dụ 5
:
t
n
- 2t
n-1
= (n+5)3
n

15
Sự biến đổi có phức tạp như sau :
-
Nhâ n 2 vế cho 9
-
Thay n bởi n+2
-
Thay n bởi n+1,sau đó nhâ n cho -6
-
Ta đ ược kế t quả :

9t
n
- 18t
n-1
= (n + 5) 3
n+2

t
n+2
- 2t
n+1
= (n + 7) 3
n+2

-6t
n+1
+ 12t
n
= -6(n + 6) 3
n+1

Cộng 3 phương trì nh lạ i ta đ ược :
t
n+2
- 8t
n+1
+ 21t
n
- 18t
n-1

= 0
Phương trì nh đặ c trưng.
x
2
- 8x
2
+ 21x - 18 = 0 hay (x-2) (x-3)
2
= 0
Ta lạ i thấ y (x-2) tương ứng vế trá i phương trì nh ban đầ u và (x-3)
2
là kế t quả
của sự biế n đổi.
Như vậ y chúng ta có thể nói rằ ng để giả i phương trì nh truy hồi không thuầ n
nhấ t có dạ ng (VII.3) ta chỉ cầ n giả i phương trì nh đặ c trưng sau.
(a
0
x
k
+ a
1
x
k-1
+ ... + a
k
) (x-b)
d+1
= 0 (VII.4)
Ví dụ 6
: (bà i toá n thá p Hà Nội)

Phương trì nh truy hồi cho bà i toá n chuyể n n đĩ a nà y có dạ ng:
1 nế u n = 1
t
n
=

{

2t
n-1
+ 1 nế u n > 1
hay t
n
= 2t
n-1
+ 1, n > 1 với t
0
= 0
Ta viế t lạ i phương trì nh :
t
n
- 2t
n-1
= 1
Và thấ y nó có dạ ng (VII.3) với b = 1, P(n) = 1 bậ c 0
Phương trì nh đặ c trưng là (x-2) (x-1) = 0
Vậ y : t
n
=c
1

1
n
+ c
2
2
n
. Từ t
0
= 0 để tì m t
1
ta viế t :
t
1
= 2t
o
+ 1 = 1
Vậ y c
1
+ c
2
= 0, n = 0
c
1
+ 2c
2
= 1, n = 1
Suy ra c
1
= -1, c
2

= 1. Vậ y t
n
= 2
n
-1
Ta nhậ n thấ y từ t
n
= c
1
1
n
+ c
2
2
n
cũng có thể kế t luậ n t
n
có O(2
n
).
16
Ví dụ 7 :
t
n
= 2t
n-1
+ n
hay t
n
- 2t

n-1
= n
ở đâ y b = 1, P(n) = n bậ c 1
Ta có phương trì nh đặ c trưng:
(x-2) (x-1)
2
= 0
Vậ y nghiệ m tổng quá t là :
t
n
= c
1
2
n
+ c
2
1
n
+ c
3
n1
n

Nế u t
n
> 0 với mỗi n thì ta có thể kế t luậ n T(n)= O(2n),
Bâ y giờ ta xé t phương trì nh truy hồi không thuầ n nhấ t tổng quá t hơn.
a
o
t

n
+a
1
t
n-1
+ ... + a
k
t
n-k
= b
1
n
p
1
(n) + b
2
n
p
2
(n) + ... (VII.5)
Trong đó b
i
là cá c hằ ng khá c nhau và p
i
(n) là cá c đa thức bậ c d
i
của n.
Bằ ng cá ch biế n đổi gầ n như tương tự với dạ ng phương trì nh (VII.1), ta có
thể viết được phương trì nh đặ c trưng cho dạ ng (VII.1)5) như sau :
(a

o
x
k
+ a
1
x
k-1
+ ... + a
k
) (x-b
1
)
d1+1
(x-b
2
)
d2+1
= 0 (VII.6)
Ví dụ 8
: Giả i phương trì nh
t
n
= 2t
n-1
+ n + 2
n
n 1
với t
o
= 0, ta có

t
n
- 2t
n-1
= n + 2
n

có dạ ng (VII.1)5) với b
1
= 1, p
1
(n) = n, b
2
= 2, p
2
(n) = 1. Bậ c của p
1
(n) là 1,
bậ c của p
2
(n) là 0. Vậ y phương trì nh đặ c trưng là :
(x-2) (x-1)
2
(x-2) = 0
Cả hai nghiệ m 1 và 2 đề u có bội là 2. Vậ y nghiệ m tổng quá t của
phương trì nh truy hồi là :
t
n
= c
1

1
n
+ c
2
n1
n
+ c
3
2
n
+ c
4
n2
n

Sử dụng dạ ng truy hồi t
n
= 2t
n-1
+ n+ 2
n
với t
o
= 0 ta có thể tí nh đ ược t
1
,
t
2
và t
3

và từ đó xác đị nh được cá c hệ số c
1
, c
2
, c
3
và c
4
qua hệ sau:
c
1
+ c
3
= 0 khi n = 0
c
1
+ c
2
+ 2c
3
+ 2c
4
= 3 n = 1
c
1
+ 2c
2
+ 4c
3
+ 8c

4
= 12 n = 2
c
1
+ 3c
2
+ 8c
3
+ 24c
4
= 35 n = 3
17
Kế t quả cuối cùng là :
t
n
= -2 -n + 2
n+1
+ n2
n

Dễ dà ng nhậ n thấ y t
n
có O(n2
n
)
Ví dụ 9
:
Giả sử n là lũy thừa của 2. Tì m T(n) từ phương trì nh:
T(n) = 4T(n/2) + n, n > 1
Thay n bằ ng 2k (với k = logn), ta có T(2k) = 4T(2k-1) + 2k. Khi đó ta có

thể viế t:
t
k
= 4t
k-1
+ 2
k

Nế u t
k
= T(2k) = T(n). Ta đ biế t cá ch giả i phương trì nh truy hồi mới nà y.
Phương trì nh đặ c trưng của nó là :
(x-4) (x-2) = 0
và từ đó ta có t
k
= c
1
4
k
+ c
2
2
k

Đặ t n ngược lạ i thay cho k, ta tì m đ ược :
T(n) = c
1
n
2
+ c

2
n
Do đó T(n) có 0(n
2
) khi n là lũy thừa của 2.
Ví dụ 10
:
T(n) = 4t(n/2) + n
2
, n > 1, lũy thừa của 2. Đặ t n = 2
k
, ta có.
T(2
k
) = 4T(2
k-1
) + 4
k

Phương trì nh đặ c trưng (x-4)2 = 0 và ta có t
k
= c
1
4
k
+ c
2
k4
k


Vậ y T(n) = c
1
n2 + c
2
n
2
logn và T(n) là 0(n
2
logn) với n lũy thừa 2.
Ví dụ 11
:
T(n) = 2T(n/2) + nlogn, n > 1
Sau khi thay n = 2k, ta có T(2
k
)= 2T(2
k-1
) + k2
k

t
k
= 2t
k-1
+ k2
k

Phương trì nh đặ c trưng (x-2)
3
= 0 và t
k

= c
1
2
k
+ c
2
k2
k
+ c
3
k
2
2
k
.
Vậ y T(n) = c
1
n + c
2
nlogn + c
3
nlog
2
n có 0(nlog
2
n), n lũy thừa 2.
18
Ví dụ 12 :
T(n) = 3T(n/2) + cn (c là const, n = 2
k

> 1)
Ta sẽ nhậ n đ ược :
T(2
k
) = 3T(2
k-1
) + c2
k
; t
k
= 3t
k-1
+ c2
k

Phương trì nh đặ c trưng là (x-3) (x-2) = 0, và do đó.
Tk = c
1
3
k
+ c
2
2
k
; T(n) = c
1
3
logn
+ c
2

n
Do alogb = bloga nê n T(n) = c
1
n
log3
+ c
2
n có 0(n
log3
),n lũy thừa 2.
c) Phương trì nh truy hồi có hệ số biế n đổi

Ta xé t ví dụ cụ thể :
T(1) = 6
T(n) = nT
2
(n/2), n > 1,n lũy thừa của 2
(hệ số ở vế phải là biến n)
Trước hế t ta đặ t t
k
= T(2
k
) và từ đấ y ta có :
t
k
= 2
k
t
2
K-1

k > 0
to = 6
Để lậ p phương trì nh truy hồi mới không có hệ số biến đổi ta đặ t V
k
= lgt
k
, ta
đ ược :
V
k
= K + 2V
k-1
k >0
V
o
= lg6
Nghĩ a là ta có hệ phương trì nh dạ ng (VI.3)
Phương trì nh đặ c trưng sẽ là
(x-2) (x-1)2 = 0
và do đó :
V
k
= c
1
2
k
+ c
2
1
k

+ c
3
k1
k

Từ V
o
= 1 + lg3, V
1
= 3+2lg3 và V
2
= 8 + 4lg3 ta tì m ra
c
1
= 3 + lg3, c
2
= -2 và c
3
= -1.
Vậ y V
3
= (3 + lg3) 2
k
- K -2
Cuối cùng, sử dụng tk = 2
vk
và T(n) = tlgn, ta đ ược :

n
nT

nn
32
)(
23

=

19
chương Ii

đệ qui
I. Khái niệm :
Đệ qui là 1 công cụ rất thường dùng trong khoa học má y tí nh và trong toá n
học để giả i quyế t cá c vấ n đề . Trước hế t, chúng ta h y khả o sá t thế nà o là một vấ n
đề có đệ qui qua ví dụ sau:
Tí nh S(n) = 1 +2 +3 +4+ ... +n
Ta nhậ n thấ y rằ ng, công thức trê n có thể diễ n đạ t lạ i như sau:
S(n) = S(n-1) + n, và
S(n-1) = S(n-2) + (n-1)
.....
S(2) = S(1) + 2
S(1) = 1
Như vậ y, một vấn đề có đệ qui là vấn đề được đị nh nghĩ a lại bằng chí nh nó.
Một cá ch tổng quá t, một chương trì nh đệ qui có thể đ ược biể u diễ n như bộ
P gồm cá c mệ nh đề cơ sở S (không chứa P) và bả n thâ n P:
P P (S
i
, P)
Để tí nh S(n)
: ta có kế t quả của S(1), thay nó và o S(2), có S(2) ta thay nó và o

S(3)...., cứ như vậ y có S(n-1) ta sẽ tí nh đ ược S(n)
Cũng như cá c lệ nh lặ p, cá c thủ tục đệ qui cũng có thể thực hiệ n cá c tí nh
toá n không kế t thúc, vì vậ y ta phả i xé t đế n vấ n đề kế t thúc cá c tí nh toá n trong
giả i thuậ t đệ qui. Rõ rà ng 1 thủ tục P đ ược gọi đệ qui chỉ khi nà o thỏa 1 điều
kiệ n B, và dĩ nhiê n điề u kiệ n B nà y phả i không được thỏa m n tạ i 1 thời điể m
nào đó. Như vậ y mô hì nh về cá c giả i thuậ t đệ qui là :
P if (B) P(S
i
, P)
hay P P(S
i
, if (B) P).
Thông thường trong cá c vòng lặ p while, để đả m bả o cho vòng lặ p kế t thúc
ta phả i đị nh nghĩ a một hà m f(x) (x là 1 biế n trong chương trì nh) sao cho nó phả i
trả về trị bằ ng 0 tạ i một thời điể m nà o đó. Tương tự như vậ y, chương trì nh đệ qui
cũng có thể đ ược chứng minh là sẽ dừng bằ ng cá ch chứng minh rằ ng hà m f(x) sẽ
giả m sau mỗi lầ n thực hiệ n. Một cá ch thường là m là kế t hợp một giá trị n với P
và gọi P một cá ch đệ qui với giá trị tham số là n-1. Điề u kiệ n B bâ y giờ là n > 0
thì sẽ đả m bả o đ ược sự kế t thúc của giả i thuậ t đệ qui. Như vậ y, ta có mô hì nh đệ
qui mới:
P(n) if (n >0) P(S
i
, P(n-1))
Hay P P (S
i
, if (n>0) P(n-1) )
20
II. Hàm đệ qui và Stack:
Một chương trì nh C thường gồm có hà m main() và cá c hà m khá c. Khi chạ y
chương trì nh C thì hà m main() sẽ được gọi chạ y trước, sau đó hà m main() gọi cá c

hà m khá c, cá c hà m nà y trong khi chạ y có thể gọi cá c hà m khá c nữa. Khi một hà m
đ ược gọi, thì một khung kí ch hoạ t của nó đ ược tạ o ra trong bộ nhớ stack. Khung
kí ch hoạ t nà y chứa cá c biế n cục bộ của hà m và mẩ u tin hoạ t động của hà m. Mẩ u
tin hoạ t động chứa đị a chỉ trở về của hà m gọi nó và cá c tham số khá c.
Biế n cục bộ
Đị a chỉ trở về Mẩ u tin
hoạ t động
{

Thông số khá c

Khung kí ch hoạ t
Sau khi hà m đ ược gọi đ thi hà nh xong thì chương trì nh sẽ thực hiệ n tiế p
dòng lệ nh ở đị a chỉ trở về của hà m gọi nó, đồng thời xóa khung kí ch hoạ t của
hà m đó khỏi bộ nhớ.
Giả sử ta có cơ chế gọi hà m trong một chương trì nh C như sau:
main()
{ ......
A();
.....;
B();
....;
}
A()
{.....;
C();
....;
D();
}
B()

{.....;
D();
}
C()
{......;
D();
.....;
}
D()
{........;
........;
}
Hì nh sau đâ y cho ta thấ y sự chiế m dụng bộ nhớ stack khi chạ y chương trì nh
C như mô tả ở trê n.
MMMMMMMMMMMMM
AAAAAAA BBB
CCC D D
D
Boọ nhụự
Stack
Thụứi gian

Tương tự với trường hợp hà m đệ qui, khi gọi đệ qui lẫ n nhau thì một loạ t
cá c khung kí ch hoạ t sẽ đ ược tạ o ra và nạ p và o bộ nhớ Stack. Cấ p đệ qui cà ng cao
21
thì số khung kí ch hoạ t trong Stack cà ng nhiề u, do đó, có khả nă ng dẫ n đế n trà n
Stack (Stack overflow). Trong nhiề u trường hợp khi lậ p trì nh, nế u có thể được, ta
nê n gỡ đệ qui cho cá c bà i toá n.
III. ví dụ


Ví dụ 1
: Hà m giai thừa:
1*2*3*......*(n-1)*n , n>0
n! =
{

1 , n=0
n*(n-1)! , n>0
n! =
{

1 , n= 0
Nhận xé t
:
- Theo công thức trê n, ta nhậ n thấ y trong đị nh nghĩ a của n giai thừa (n!) có
đị nh nghĩ a lạ i chí nh nó nê n hà m giai thừa có đệ qui.
- Điề u kiệ n dừng tí nh hà m giai thừa là n=0, khi đó n! = 1
- Hà m đệ qui
:
long giaithua(int n)
{
if (n == 0)
return(1);
else
return(n * giaithua(n-1));
}
hay:
long giaithua(int n)
{ return ((n==0) ? 1 : n*giaithua(n-1));
}

- Hà m không đệ qui
:
long giaithua (int n)
{ long gt=1;
for (int i=1; i<=n; i++)
gt= gt * i ;
return (gt);
}
22
Ví dụ 2: Hà m FIBONACCI:

F
n
=
{

1 ; n =0,1
F
n-1
+ F
n-2
; n>1
Nhận xé t
:
- Theo đị nh nghĩ a trê n, hà m Fibonacci có lời gọi đệ qui.
- Quá trì nh tí nh dừng lạ i khi n= 1
- Hà m đệ qui
:
long fib(int n)
{ if (n==0 || n==1)

return 1 ;
else return(fib(n-1) + fib(n-2));
}
- Hà m không đệ qui
:
long fib(int n)
{ long kq, Fn_1, Fn_2;
kq = 1;
if (n > 1)
{
Fn_1 = 1;
Fn_2 = 1;
for (int i=2; i<=n; i++)
{
kq = Fn_1 + Fn_2 ;
Fn_2 = Fn_1;
Fn_1 = kq;
}
}
return (kq);
}
Ví dụ 3
: Bà i toá n Thá p Hà nội
Có 3 cột A, B, C. Cột A hiệ n đang có n dĩ a kí ch thước khá c nhau, dĩ a nhỏ ở
trê n dĩ a lớn ở dưới. H y dời n dĩ a từ cột A sang cột C (xem cột B là cột trung
gian) với điề u kiệ n mỗi lầ n chỉ đ ược dời 1 dĩ a và dĩ a đặ t trê n bao giờ cũng nhỏ
hơn dĩ a đặ t dưới.
23
- Giả i thuậ t đệ qui: Để dời n dĩ a từ cột A sang cột C (với cột B là cột trung
gian), ta có thể xem như :

+ Dời (n-1) dĩ a từ cột A sang cột B ( với cột C là cột trung gian)
+ Dời dĩ a thứ n từ cột A sang cột C
+ Dời (n-1) dĩ a từ cột B sang cột C ( với cột A là cột trung gian)
- Chương trì nh
:
void hanoi (int n, char cotA, char cotC, char cotB)
{
if(n == 1)
printf("\n%s%c%s%c", " chuyen dia 1 tu cot ", cotA, " den cot ", cotC);
else
{
hanoi(n-1, cotA, cotB, cotC);
printf("\n%s%d%s%c%s%c", " chuyen dia ", n, " tu cot ", cotA,
" den cot ", cotC);
hanoi(n-1, cotB, cotC, cotA);
}
}
IV. CáC THUậT TOáN LầN NGƯợC
:
Trong lậ p trì nh, đôi khi ta phả i xá c đị nh cá c thuậ t giả i để tì m lời giả i cho
cá c bà i toá n nhấ t đị nh nhưng không phả i theo một luậ t tí nh toán cố đị nh, mà
bằ ng cá ch thử-và -sai. Cá ch chung là phâ n tí ch thử-và -sai thà nh những công việ c
cục bộ. Thông thường công việ c nà y đ ược thực hiệ n trong dạ ng đệ qui và bao
gồm việ c thă m dò một số hữu hạ n cá c nhiệ m vụ nhỏ. Trong bà i giả ng nà y ta
không tì m hiể u cá c qui tắ c tì m kiế m tổng quá t, mà chỉ tì m những nguyê n lý
chung để chia việ c giả i bà i toá n thà nh những việ c nhỏ và ứng dụng của sự đệ qui
là chủ đề chí nh. Trước hế t, ta minh họa kỹ thuậ t că n bản bằ ng cá ch xé t bà i toá n
m đi tuầ n.
Ví dụ 1
. Bà i toá n m đi tuầ n.

Cho bà n cờ có n x n ô. Một con m đ ược phé p đ i theo luậ t cờ vua, đầ u tiê n
nó đ ược đặt ở ô có toạ độ x
0
, y
0
. Câ u hỏi là , nế u có thì h y tì m cá ch sao cho con
m đi qua đ ược tấ t cả cá c ô của bà n cờ, mỗi ô đi qua đúng 1 lầ n.
* Luậ t đi của con m trê n bà n cờ: Tạ i một ô có tọa độ cột x
0
,

hà ng y
0
(x
0
,y
0
)
trê n bà n cờ, con m có 1 trong 8 nước đi như sau:
24
3 2
4 1

Con
M

5 8
6 7
Hì nh 2.1 8 nước đi có thể của con m xuất phát từ cột x
0

, hàng y
0
.
Với tọa độ bắ t đầ u (x
0
,y
0
), có tấ t cả 8 ô (u,v) mà con m có thể đi đến được.
Chúng đ ược đánh số từ 1 đế n 8 trong hì nh 2.1
Phương pháp đơn giản để có được u,v từ x,y là cộng cá c chê nh lệ ch cột,
dòng về tọa độ đ ược lưu trong 2 mả ng a và b. Cá c giá trị trong 2 mả ng a, b đ
đ ược khởi động thí ch ứng như sau:
Ta xem như có 1 hệ trục tọa độ (Oxy) ngay tạ i vị trí (x
0
,y
0
) của con m , thì :
+ Vị trí 1 mà con m có thể đi đ ược là :
u= x
0
+ 2, v = y
0
+ 1
+ Vị trí 2 mà con m có thể đi đ ược là :
u= x
0
+ 1, v = y
0
+ 2
+ Vị trí 3 mà con m có thể đi đ ược là :

u= x
0
+ (-1), v = y
0
+ 2 ....
Như vậ y, mả ng a và b có giá trị sau:
int a[8] = {2, 1, -1,-2, -2, -1, 1, 2};
int b[8] = {1, 2, 2, 1, -1, -2,-2, -1};
* Cá ch biể u diễ n dữ liệ u: Để mô tả đ ược bà n cờ, ta dùng ma trậ n BanCo
theo khai bá o sau:
#define KICHTHUOC 5 // Kí ch thước của bà n cờ
int BanCo[KICHTHUOC][KICHTHUOC]; // Tổ chức bà n cờ là mng hai chiề u
Ta thể hiệ n mỗi ô cờ bằ ng 1 số nguyê n để đá nh đấ u ô đó đ đ ược đi qua
chưa, vì ta muốn lầ n dò theo quá trì nh di chuyể n của con m . Và ta qui ước như
sau:
BanCo [x][y]=0 ; ô (x,y) chưa đi qua
BanCo [x][y]=i ; ô (x,y) đ đ ược đi qua ở nước thứ i ( 1 i n
2
)
25
* Thuật giải:
Cá ch giả i quyế t là ta phả i xé t xem có thể thực hiệ n một nước đi kế nữa hay
không từ vị trí x
0
, y
0
. Thuậ t giả i để thử thực hiệ n nước đi kế.
void thử nước đi kế
{ khởi động cá c chọn lựa có thể đi
do

{ chọn một nước đi;
if chấ p nhậ n đ ược
{ ghi nhậ n nước đi;
if bà n cờ chưa đầ y
{ thử nước đi kế tạ i vị trí vừa ghi nhậ n đ ược;
if không đ ược
xóa nước đi trước
}
}
} while (không đi đ ược && còn nước đi)
}
* Nhận xé t
:
- Để xá c đị nh tọa độ (u,v) của nước đi kế ( 0 i 7 ), ta thực hiệ n như sau:
u = x + a[i] ; v = y + b[i]
- Điề u kiệ n để nước đi kế chấ p nhậ n đ ược là (u,v) phả i thuộc bà n cờ và con
m chưa đi qua ô đó, nghĩ a là ta phả i thỏa cá c điề u kiệ n sau:
(0 u <KICHTHUOC && 0 v< KICHTHUOC && BanCo[u][v]==0 )
- Ghi nhậ n nước đi thứ n, nghĩ a là BanCo [u][v] = n; còn bỏ việ c ghi nhậ n
nước đi là BanCo [u][v] = 0
- Bà n cờ đầ y khi ta đ đi qua tấ t cả cá c ô trong BanCo, lúc đó :
n = KICHTHUOC
2
.
Qua nhậ n xé t trê n, ta có thuậ t giả i chi tiế t hơn như sau:
void thu_nuoc_di(int n, int x, int y, int &q) // thử 8 cá ch đi của con m tạ i
// nước thứ n xuất phát từ ô (x,y)
{ int u,v, q1;
khởi động cá c chọn lựa có thể đi

×