Download as pdf or txt
Download as pdf or txt
You are on page 1of 10

Đệ qui - Recusion

TS. Trần Thanh Hải


Đệ quy là gì?

• Một đối tượng được mô tả thông qua chính nó được gọi


là mô tả đệ quy.
• Một bài toán mang tính chất đệ quy khi nó có thể được
phân rã thành các bài toán nhỏ hơn nhưng mang cùng
tính chất với bài toán ban đầu, các bài toán nhỏ lại được
phân rã thành các bài toán nhỏ hơn nữa.
• Hàm đệ quy
• Trong lập trình, một hàm được gọi là đệ quy khi nó gọi
chính nó trong thân hàm.
void Recusion()
{
Recusion();
}
Đệ qui - Recusion

• Hàm đệ quy gồm 2 phần:


Phần cơ sở: Điều kiện thoát khỏi đệ quy.
Phần đệ quy: Thân hàm có chứa lời gọi đệ quy.
• Thiết kế giải thuật đệ quy (3 bước):
+ Tham số hóa bài toán.
+ Phân tích trường hợp chung: Đưa bài toán về bài toán
nhỏ hơn cùng loại, dần dần tiến tới trường hợp suy biến.
+ Tìm trường hợp suy biến.
Đệ qui

• Khi gọi hàm đệ qui đến chính nó thì mỗi lần gọi, thì máy tạo ra
một tập các biến cục bộ hoàn toàn mới độc lập với các tập
biến (cục bộ đã được tạo ra trong các lần gọi trước).
• Chú ý: có bao nhiêu lần gọi tới hàm thì cũng có bấy nhiêu lần
thoát ra khỏi hàm và cứ mỗi lần ra khỏi hàm thì tập các biến
cục bộ bị xóa.
• Sự tương ứng giữa các lần gọi tới hàm và các lần ra khỏi hàm
được thực hiện theo thứ tự ngược: nghĩa là lần ra đầu tiên
ứng với lần vào cuối cùng và lần ra khỏi hàm cuối cùng ứng
với lần đầu tiên gọi tới hàm.
• Hàm đệ qui dùng nhiều vùng nhớ trên ngăn xếp và có thể dẫn
đến tràn ngăn xếp. (nên dùng cho bài toán chỉ giải được bằng
đệ qui)
Một số loại đệ quy

• Đệ quy tuyến tính (Linear Recursion)


Mỗi lần thực thi chỉ gọi đệ quy một lần (hàm tính giai
thừa)
• Đệ quy nhị phân (Binary Recursion)
Mỗi lần thực thi có thể gọi đệ quy 2 lần, (Tính tổ hợp
chập K của N bằng đệ quy)
• Đệ quy lồng (Nested Recursion)
• Đệ quy hỗ tương (Mutual Recursion) (Các hàm gọi đệ
quy lẫn nhau)
Ví dụ 1: Tính giai thừa sử dụng for

int giaithua(int n)
{
int outn = 1;
for(int i = 1; i<n+1; i++)
outn = outn*i; // = 1.2.3..(n-2)(n-1)n
return outn;
}
Ví dụ 2 : tính giai thừa n! = n(n-1)..1 – Giải đệ quy

int Factorial(int n) { // dải số nguyên int -2147483648 tới 2147483647


if (n == 0){ // phần 1 cơ sở: điều khiển thoát khỏi đệ quy
return 1;
}
else{ // phần 2: thân hàm có chứa lời gọi đệ quy
return (n * Factorial(n - 1)); // Linear Recursion
}
} // do đó chỉ số thể dùng đến n = 15!
• Mở rộng kiểu: với dải unsigned int từ 0 tới 4294967295
• Ví dụ 2_1.
Ví dụ 2 : tính giai thừa n! = n(n-1)..1 - Minh họa

• Tính giai thừa của 5! = 5.4.3.2.1 (tuyến tính)


Ví dụ 3: tính xn

double mu(double x, int n)


{
if(n==0) { // điều kiện dừng
return 1;
}
else{ // thân hàm có chứa đệ qui
return x*mu(x,n - 1);
}
}
Bài tập liên quan đến toán

• Giải các phương trình đệ quy sau với T(1)=1:


• 1. T(n)=3T(n/2)+n
• 2. T(n)=4T(n/3)+n
• 3. T(n)=T(n/2)+1
• 4. T(n)=2T(n/2)+logn
• 5. T(n)=2T(n/2)+n
• Bài 1: s(n) = (2n)!
• Bài 2: 13 + 23 +…+ n3.
• Bài 3: Tính gần đúng:
x x2 xn
e  1    
x

1! 2! n!

You might also like