Trư
ng ði hc Nông nghip 1
-
Gi
áo
tr
ình
p
tr
ình
n
â
ng cao
..............................................................
-

Chương 5
Gii thut ñ quy
Ni dung ca chương này ñ cp ñn nhng bài toán có tính ñ quy. Không phi bài
toán nào cũng có tính ñ quy và không phi các bài toán có tính ñ quy thì ñu phi gii b(ng
gii thut ñ quy. Các vn ñ c%n quan tâm trong chươngy:
Bài toán có tính ñ quy không
Có c%n dùng gii thut ñ quy không
ð quy có mang li hiu qu hơn các phương pháp thông thưng hay không
Trư
ng ði hc Nông nghip 1
-
Gi
áo
tr
ình
p
tr
ình
n
â
ng cao
..............................................................
-

1. Khái nim ñ quy
Trong thân mt chương trình con th ñưa li gi ti chính chương trình con ñó, tính
cht này ñưc gi là tính "ð qui ca chương trình con".
Trong toán hc khái nim giai th a ñưc ñ"nh nghĩa như sau:
0! = 1
Nu n > 0 thì n! = 1*2*3*...*n
T ñ"nh nghĩa trên d, dàng thy r(ng
n! = n*(n-1)!
(n-1)! = (n-1)*(n-2)!
......
1! = 1*0! =1
Cách thc lp lun như trên ñưa chúng ta ti mt nhn xét t!ng quát là: li gii ca bài
toán A có th ñưc thc hin bi li gii ca bài toán A' có dng ging như A. Tht vy, vic
tính n! có th ñưc thc hin bi vic tính (n-1)!.
ðiu quan trng ñ bài toán li gii tuy A' ging như A song thc cht A' phi
nh/ hơn A và quá trình "thu nh/" phi có ñim d ng. Trong bài toán tính giai th a t ch' c%n
tính giai th a ca n chúng ta ñi tính giai th a ca (n-1), ñ tính giai th a ca (n-1) chúng ta ñi
tính giai th a ca (n-2)... kt thúc là giai th a ca 0.
Mt ñi tưng ñưc gi là ñ quy nu nó ñưc ñ"nh nghĩa dưi dng ca chính nó.
Gii thut ca bài toán A ñưc gi là ñ quy nu nó dn ti vic gii bài toán A' ging
như A nhưng nh/ hơn A và quá trình phiñim d ng.
Xét bài toán tính giai th a vi n = 5:
Ô nh cui 1! = 1
2! = 2*1!
3! = 3*2!
4! = 4*3!
Ô nh ñ%u 5! = 5*4!
Hình 5.1
Như vy khi bit 1! thì tính ñưc 2!, bit 2! Thì tính ñưc 3!,...
B(ng cách s dng b nh ngăn xp theo nguyên t&c LIFO ( Last In - First Out) (Hình
1.3) nhng gì gi vào cui cùng thì ñưc ly ra trưc tiên. Bóc ô nh trên ñ)nh ta1! = 1
l ra ô tip theo 2! = 2*1!. 1! ñã bit nên tính ñưc 2! = 2, bóc tip ô nh phía dưi ta
3! = 3*2!, vì 2! ñã bit nên 3! = 3*2 = 6 quá trình tip tc cho ñn khi bóc ô nh dưi cùng và
chúng ta nhn ñưc 5! = 120. Dưi ñây là chương trình tính giai th a
5! = 5*4!
4! = 4*3!
3! = 3*2!
2! = 2*1!
1! = 1
Trư
ng ði hc Nông nghip 1
-
Gi
áo
tr
ình
p
tr
ình
n
â
ng cao
..............................................................
-

Ví d 5.1:
Program Giaithua;
Uses crt;
Var n: integer;
Function GT(m: integr): integer; (* Hàm GT tính giai th a ca n*)
Begin
if m=0 then GT:=1 else GT:= m*GT(m-1); (*Gi ñ qui ca GT *)
End;
Begin
Clrscr;
write ('Tinh giai thua cua n = '); Readln (n) (*ðc giá tr" n*)
write('Gia thua cua ',n, ' = ',GT(n)); (* Vit giá tr" hàm GT *)
Repeat until keypressed;
End.
Ví d 5.1 có mt s! ñi u ñáng lưu ý sau ñây:
1. Hàm GT ñưc xây dng ñ tính giai th a vi tham s hình thc m, kiu ca m là kiu
Integer. Giá tr" m sau này s$ ñưc thay th b(ng tham s thc n qua li gi GT(n) trong
chương trình m+.
2. Khi ñ"nh nghĩa kiu ca GT Integer thì giá tr" ca n ch) ñưc chn nh/ hơn 8 8!
= 40320 vưt quá giá tr" cc ñi ca Integer (32767). ð có th tính giai th a vi n>=8 ta phi
ñ"nh nghĩa function GT có kiu Longint ho#c Real. Vi kiu Real lnh vit gtr" ca giai
th a phi là vit s thc vi ph%n l0 b(ng 0, ví d:
Write (GT(n):12:0);
3. S dng thut toán ñ quy ñng nghĩa vi vic phi xây dng chương trình con,
vy nu s dng các vòng l#p có th gii ñưc bài toán thì nên dùng vòng l#p. Tr trưng hp
b&t buc phi gii bài toán không có tính l#p ho#c bài toán có kh năng truy hi.
Vi bài toán tính giai th a có th dùng vòng l#p chúng ta thy chương trình s$ ñơn
gin hơn nhiu so vi cách dùng tính ñ quy:
Ví d 5.2
Program Tinh_GT;
Uses crt;
Var i,n:byte; gt:longint;
Begin
Clrscr;
Write(' Nhap gia tri n '); Readln(n);
if (n = 0) or (n=1) then gt:=1;
if n > 1 then gt:=1;
For i:= 1 to n do gt:=gt*i;
Writeln('Giai thua cua ',n,' = ',gt);
Trư
ng ði hc Nông nghip 1
-
Gi
áo
tr
ình
p
tr
ình
n
â
ng cao
..............................................................
-

Readln;
End.
Ví d 5.3: Lp chương trình tìm ưc s chung ln nht ca hai s nguyên n, m.
Ưc s chung ln nht ca hai s n và m tính theo công thc :
n nu m = 0
USC(n,m) =
USC(m, n mod m ) nu m <> 0
Ví d n= 4, m=8
USC(4,8) = USC(8, 4) = USC(4,0) = 4
Chương trình ñưc xây dng như sau:
Program timUSC ;
Uses crt;
Var n,m : word; Lam: Char;
FUNCTION USC(a,b:word): word;
Begin
If b=0 then USC := a Else USC := USC(b,a mod b);
End;
BEGIN
Repeat
Clrscr;
Write(' Hay cho hai so "n" va "m" can tim uoc so chung ');
Readln(n,m);
Writeln(' Uoc so chung lon nhat cua ',n,' va ',m, ' la ',USC(n,m):5);
Writeln;
Write('Tim tiep hay thoi ? C/K '); read(lam);
Until Upcase(lam)='K';
END.
Bài toán kinh ñin ng dng gii thut ñ quy bài toán Tháp Hanoi. Ni dung bài
toán như sau:
Có n chic ñĩa tròn ñưng kính khác nhau, các ñĩa có l' gia. Ngưi ta xp lng các
ñĩa này vào mt cc theo th t trên nh/ dưi to. Yêu c%u phi xp các ñĩa này sang cc mi
theo nguyên t&c:
1. M'i l%n ch) ñưc chuyn 1 ñĩa
2. Không ñưc ñ xy ra tình trng ñĩa to trên, ñĩa nh/ dưi dù là tm thi
3. ðưc phép dùng mt cc trung gian
Trư
ng ði hc Nông nghip 1
-
Gi
áo
tr
ình
p
tr
ình
n
â
ng cao
..............................................................
-

Gi s cc ñ%u tiên cc A, cc trung gian là B cc c%n xp ñĩa sang cc C.
Chúng ta s$ xét mt s trưng hp ñơn gin ñ tìm quy lut (Hình 5.2)
* n =1: cc A ch) có mt ñĩa
Chuyn ñĩa t cc A sang cc C
Kt thúc
A B C
Hình 5.2
* n = 2: cc A có 2 ñĩa (Hình 5.3)
Chuyn ñĩa trên sang B
Chuyn ñĩa dưi sang C
Chuyn ñĩa t B sang C
Kt thúc
A B C C
Hình 5.3
* n = 3: cc A có 3 ñĩa
Vi trưng hp 3 ñĩa nu chúng ta coi 2 ñĩa trên mt ñĩa thì bài toán quy v trưng
hp n = 2, khi ñó li gii s$ là: (Hình 5.4)
Chuyn 2 ñĩa trên sang B
Chuyn ñĩa dưi cùng sang C
Chuyn 2 ñĩa t B sang C
Kt thúc