Tài liệu chuyên tin 11 - Hà Tây
Chơng I : Duyệt không đệ qui
I / Nhận xét :
Các chơng trình có thể viết dới dạng Duyệt bằng đệ quy khi nó phải thực hiện
nhiệm vụ P có hình thức đệ quy sau đây :
trong đó S
là một số công việc phải thực hiện khi có điều kiện kết thúc B
0
của đệ quy , còn
B
k
là điều kiện cần để thực hiện nhiệm vụ P ở bớc thứ k . Trong mỗi bớc gọi thực hiện P
thì điều kiện B
k
đợc thu hẹp dần để dẫn tới tình trạng kết thúc B
0
của quá trình duyệt .
Song do chơng trình đệ quy đợc tổ chức bằng Stack (ngăn xếp) trong bộ nhớ có
kích thớc tối đa là 16kb nên khi gặp những chơng trình đệ quy quá sâu thờng bị tràn Stack
của bộ nhớ ( ngăn xếp của chơng trình đệ quy không đủ chứa các hàm và thủ tục đệ quy
của nó ) . Trong những trờng hợp nh thế , ngời ta thờng chuyển sang chơng trình viết dới
dạng Duyệt không đệ qui thay đệ quy bằng vòng lặp , dựa vào công thức sau :
G
0
: một số lệnh gán trị ban đầu
B
k
: điều kiện cần để thực hiện công việc P
k
II / Một số thí dụ :
Thí dụ 1 : Xây dựng hàm Fibonaci bằng đệ quy và không đệ quy
Function Fibonaci(N : Integer) : Integer;
Begin
If N=0 then Fibonaci =1 {N=0 hoặc N=1 là điều kiện B
0
}
Else
If N=1 then Fibonaci =1
Else {N>=2 là điều kiện B
k
}
Fibonaci := Fibonaci(N-1)+ Fibonaci(N-2)
End;
Function Fibonaci(N : Integer) : Integer;
Var i,p,U0,U1 : Integer;
Begin
i := 0;
U0 := 0;
U1 := 1;
While i< N do
Begin
Inc(i);
___________________________
CHƯƠNG I : KHÔNG Đệ QUI TDH 9/2/2013 9/2/2013
P = ( Nếu B
0
thì S
; Nếu B
k
thì P )
P = ( G
0
; Trong khi B
k
thì P
k
)
Tài liệu chuyên tin 11 - Hà Tây
p := U1;
U1 := U0+U1;
U0 := p;
End;
Fibonaci := p;
End;
Thí dụ 2 : Sắp xếp mảng bằng thuật toán QuickSort :
Kiểu đệ quy
Program QSort;
{$R-,S-}
Uses Crt;
Const Max = 30000;
Type List = Array[1..Max] of Integer;
Var Data : List;
I : Integer;
Procedure QuickSort(Var A: List; Lo, Hi: Integer);
Procedure Sort(L, r: Integer);
Var i, j, x, y: integer;
Begin
i := L;
j := r;
x := a[(L+r) DIV 2];
Repeat
While a[i] < x do i := i + 1;
While x < a[j] do j := j - 1;
If i <= j then
Begin
y := a[i];
a[i] := a[j];
a[j] := y;
i := i + 1;
j := j - 1;
End;
until i > j;
If L < j then Sort(L, j);
If i < r then Sort(i, r);
End;
Begin
Sort(Lo,Hi);
End;
BEGIN {QSort}
Write('Hiện đang tạo ',max ,' số ngẫu nhiên...');
Randomize;
___________________________
CHƯƠNG I : KHÔNG Đệ QUI TDH 9/2/2013 9/2/2013
Tài liệu chuyên tin 11 - Hà Tây
For i := 1 to Max do Data[i] := Random(30000);
Writeln;
Write('Hiện đang sắp xếp các số...');
QuickSort(Data, 1, Max);
Writeln;
For i := 1 to Max do Write(Data[i]:8);
Readln;
END.
Kiểu không đệ quy
Uses Crt;
Const MN = 4000;
Type cs = 1..MN;
Pt = Record
ma : Cs;
gt : Integer;
End;
M1 = Array[1..MN] of pt;
M2 = Array[1..MN] of Record tr,ph : cs End;
Var i,N : cs;
A : M1;
B : M2;
Procedure H;
Var s,i,j,tr,ph : cs;
x : Integer;
coc : Pt;
Begin
s := 1; {Công việc G
0
: Nạp phần tử thứ nhất vào Stack B}
B[s].tr := 1;
B[s].ph := N;
Repeat {Thực hiện cho đến gặp điều kiện kết thúc B
0
: Stack rỗng ( s=0)}
tr := B[s].tr; { Lấy 1 phần tử ở đỉnh Stack }
ph := B[s].ph;
Dec(s);
Repeat { Điều kiện thực hiện 1 lần sắp xếp là : tr<ph }
i := tr;
j := ph;
x := A[(tr+ph) div 2].gt;
Repeat
While A[i].gt<x do inc(i);
While A[j].gt>x do dec(j);
If i<=j then
Begin
coc := A[i];
A[i] := A[j];
A[j] := coc;
Inc(i);
Dec(j);
___________________________
CHƯƠNG I : KHÔNG Đệ QUI TDH 9/2/2013 9/2/2013
Tµi liÖu chuyªn tin 11 - Hµ T©y
End;
Until i>j;
If i<ph then
Begin
Inc(s);
B[s].tr := i;
B[s].ph := ph;
End;
ph := j;
Until tr >= ph;
Until s = 0;
End;
Procedure DocF;
Const Fi = 'qsort0dq.txt';
Var F : Text; i : cs;
Begin
Assign(F,Fi);
Reset(F);
Readln(F,N);
For i:=1 to N do
Begin
Readln(F,A[i].gt);
A[i].ma := i;
End;
Close(F);
End;
Procedure Hienkq;
Var i : Cs;
Begin
For i:=1 to N do Write(A[i].ma:4);
Writeln;
For i:=1 to N do Write(A[i].gt:4);
End;
Procedure TaoF;
Const Fi = 'qsort0dq.txt';
Var F : Text; i : cs;
Begin
Assign(F,Fi);
ReWrite(F);
N := 4000;
Writeln(F,N);
For i:=1 to N div 2 do Writeln(F,i);
For i:= N div 2+1 to N do Writeln(F,i-(N div 2));
Close(F);
End;
Begin
TaoF;
DocF;
H;
___________________________
CH¦¥NG I : KH¤NG §Ö QUI TDH 9/2/2013 9/2/2013
Tài liệu chuyên tin 11 - Hà Tây
Hienkq;
End.
Thí dụ 3 :
Cho 3 ký tự A,B,C . Hãy tạo xâu có độ dài M<=250 chỉ chứa 3 ký tự này có tính chất :
Không có 2 xâu con liền nhau bằng nhau .
Kiểu đệ quy
Uses Crt;
Const N = 20;
Var S : String;
Function Kt(S : String) : Boolean;
Var i,j : Byte;
Begin
Kt := True;
For i:=1 to Length(S) div 2 do
For j:=1 to Length(S)- 2*i+1 do
If Copy(S,j,i)=Copy(S,j+i,i) then
Begin
Kt := False;
Exit;
End;
End;
Procedure Tao(S : String);
Var ch : Char;
Begin
If Length(S)=N then
Begin
Writeln(S);
Readln;
Halt;
End;
For ch:='A' to 'C' do { Khởi tạo mọi khả năng }
Begin
S := S+ch; { Thử chọn 1 khả năng }
If Kt(S) then Tao(S) {Nếu thoả mãn điều kiện thì tìm tiếp }
Else Delete(S,Length(S),1); {Nếu không thì trả về trạng thái cũ}
End;
End;
BEGIN
Clrscr;
S := '';
Tao(S);
END.
Cách giải đệ quy ở trên chỉ áp dụng đợc khi Length(S)<=20 . Sau đây là cách giải không
đệ quy , có thể áp dụng với S có Length(S) <=250 .
___________________________
CHƯƠNG I : KHÔNG Đệ QUI TDH 9/2/2013 9/2/2013