4.1. Khái niệm
Một đối t−ợng gọi là có tính đệ quy nếu nó bao gồm chính nó hoặc đ−ợc định nghĩa thông qua chính nó.
Trong C, một hàm có thể có lời gọi tới chính nó, đó là tính đệ quy của hàm.
- Bức tranh đệ quy. - Biểu thức đệ quy: i = i + 1; 1 nếu n= 0 n! = n(n-1)! nếu n > 0 - 4.2. Cách xây dựng hàm đệ quy
Hàm đệ quy th−ờng đ−ợc viết theo thuật toán sau:
if (tr−ờng hợp suy biến) {
Trình bầy cách giải bài toán (giải định đã có cách giải) }
else // tr−ờng hợp chung {
Gọi đệ quy tới hàm với các giá trị khác nhau của tham số }
Ví dụ: Hàm tìm USCLN của hai số nguyên d−ơng.
int USCLN(int x, int y) {
if (x == y) return x; else
if (x > y) return USCLN(x-y, y); else USCLN(x, y-x);
}
4.3. Ví dụ
Ví dụ 1: tính giai thừa n! bằng ph−ơng pháp đệ quy.
# include <iostream.h> # include <conio.h>
// Tinh giai thua bang lap long gthua(int &n)
{ long gt = 1;
return gt; }
// Tinh giai thua bang de quy long gtdq(int n) { if (n == 0 || n == 1) return 1; else return n*gtdq(n-1); } void main() { int k; clrscr();
cout << "\nVao mot so nguyen khong am n = "; cin >> k;
cout << k << "! = " << gtdq(k); getch();
}
Ví dụ 2: Lập ch−ơng trình tìm dãy số Fibonacci có tính chất nh− sau : F0 = 0, F1 = 1
Fn = Fn-1 + Fn-2
# include <iostream.h> # include <conio.h> # include <iomanip.h>
// Tim day Fibonacci bang PP lap void fibo1(int n)
{
int f0 = 0, f1 = 1, f2;
cout << "\nf0 = 0" << "\nf1 = 1"; for (int i=2; i<=n; i++)
{ f2 = f1+f0; f2 = f1+f0; cout << "\nf" << i << " = " << f2; f0 = f1; f1 = f2; } }
// Tim day Fibonacci bang PP lap long fibo2(int n) { if (n == 0) return 0; else if (n==1) return 1; else { int f0 = 0, f1 = 1, f2; for (int i=2; i<=n; i++) { f2 = f1+f0; f0 = f1; f1 = f2; } return f2; } }
// Tim day Fibonacci bang PP de quy long fibodq(int n)
{
if (n==0) return 0; else
if (n==1) return 1;
else return (fibodq(n-2)+fibodq(n-1)); }
void main() {
int k = 9; clrscr();
cout << "\nDay " << k+1 << " so Fibonacci:"; //fibo1(k);
//for (int i=0;i<=k; i++)
// cout << setw(5) << fibo2(i); for (int i=0;i<=k; i++)
cout << setw(5) << fibodq(i); getch();
4.4. Chú ý
• Ưu điểm của phép đệ quy là làm cho CTC trở nên gắn gọn và dễ
hiểu. Xong mỗi lần gọi đệ quy, trên Stack xuất hiện các tham biến trị và cục bộ mới, dẫn tới tốn nhiều ô nhớ và thời gian.
• Chỉ nên dùng đệ quy với những bài toán và các cấu trúc dữ liệu
mà bản thân chúng đ−ợc định nghĩa theo lối đệ qui. Nói chung nên tránh dùng phép đệ quy khi có thể dùng phép lặp để tính toán.
• Việc chuyển viết một hàm theo ph−ơng pháp đệ quy bằng
Ch−ơng 4 Mảng và chuỗi