You are on page 1of 2

§1.

Đệ Quy và Hàm Đệ Quy


1. Khái niệm đệ quy:
- Đệ quy là một hiện tượng, sự vật có tính chất lặp lại giống nó hoặc được nghĩa theo
chính nó.
→ Các định nghĩa sử dụng đệ quy trong mô tả sự vật, hiện tượng thường ngắn ngọn
và dễ hiểu.

2. Khái niệm hàm đệ quy:


- Hàm đệ quy trong tin học là một hàm mà trong đó tự nó gọi lại chính nó.
→ Các viết hàm đệ quy thường ngắn ngọn và dễ hiểu, dễ giải thích.
- Tuy nhiên việc gọi lại hàm liên tục nếu không có điểm dừng sẽ tạo thành một
vòng lặp chạy vô hạn và ta sẽ không tìm được đáp án cho bài toán chính vì vậy
mà trong một chương trình đệ quy, ta luôn có 2 thành phần là phần cơ sở và công
thức truy hồi:
o Phần cơ sở là giá trị ban đầu của bài toán, được dùng làm cơ sở để dừng
việc tự gọi chính nó của hàm đệ quy.
o Công thức truy hồi là thủ tục để thực hiện giải quyết các phần tử tiếp theo
của bài toán khi điều kiện dừng ở phần cơ sở đã được đáp ứng.
- Cấu trúc của một chương trình đệ quy trong C++:
<kiểu dữ liệu hàm> <tên hàm>(<các tham biến>){
if(<điều kiện dừng>){
return <kết quả khi đạt được điều kiện>;
} → Đây là phần cơ sở
else{
<các lệnh thực hiện>
return <tên hàm>(<sự thay đổi của các tham biến>);
} → Đây là công thức truy hồi
} → Đây là hàm đệ quy

Ví dụ hàm tính n!
Ta đã biết theo địnhnghĩa ,n !=n∗( n−1 )∗…∗2∗1
Ta đã biết theo quy ước , 0 !=1
Ta cũng đã biết 1 !=1
Dựa vào định nghĩa tanói được rằng n !=n∗( n−1 ) !

Như vậy ta có :
{n !=n∗(nn−1
!=1 với n ≤1 → Đây là phần cơ sở
) ! với n> 1→ Đây là công thức truy hồi
int giaithua(int n){
if(n == 0 || n==1)return 1; → Phần cơ sở
Tiến hành viết chương trình ta được:
else return n*giaithua(n-1); → Phần truy hồi
} → Hàm đệ quy
Việc ứng dụng đệ quy đã làm xuất hiện các thuật toán giải quyết các vấn dề cơ bản về
thời gian trong lập trình ví dụ như là thuật toán tìm kiếm nhị phân.
Đặt vấn đề: “Vì sao cần có thuật toán tìm kiếm nhị phân?”
Trong một mảng đã sắp xếp theo một trật tự nhất định. Với một giá trị k cho trước, ta
cần tìm vị trí của k trong dãy đã cho sao cho tối ưu được thời gian thay vì phải tìm
kiếm lần lượt k thông qua các vòng lặp for (Với trường hợp tệ nhất là O(n) tức là xét
hết cả mảng mà không tìm được k) chính vì vậy thuật toán tìm kiếm nhị phân ra đời
để giải quyết vấn đề này.
Tư tưởng của thuật toán:
- Thuật toán tìm kiếm nhị phân dùng cho một mảng mà ở đó các giá trị được sắp xếp
theo một trật tự nhất định ví dụ dưới đây là theo trình tự sắp xếp không giảm. Với số
k cho trước và tìm vị trí của số k trong dãy đã cho là tối ưu nhất.
- Đầu tiên, thuật toán tìm kiếm nhị phân tìm ở vị trí ở chính giữa dãy đã cho
- Tiếp theo, so sánh giá trị ở chính giữa dãy đã cho với k:
+ Nếu vị trí ở chính giữa dãy là k thì trả về vị trí ở chính giữa dãy
(Đây là điều kiện dừng nếu tìm thấy k)
+ Nếu vị trí ở chính giữa dãy lớn hơn k tức là k nằm ở phía bên trái của vị trí chính
giữa như vậy lúc này ta giới hạn lại khu vực cần tìm là từ vị trí left → mid-1
+ Nếu vị trí ở chính giữa dãy nhỏ hơn k tức là k nằm ở phía bên phải của vị trí chính
giữa như vậy lúc này ta giới hạn lại khu vực cần tìm là từ vị trí mid+1 → right
- Cuối cùng nếu không tìm thấy k thì ở lần gọi cuối cùng, hàm trả về left = mid+1
hoặc right = mid-1 làm cho left > right. Như vậy đây là điều kiện để dừng gọi nếu
không tìm thấy
Đưa thuật toán vào lập trình ta có chương trình sau:
int Timkiemnp(int arr[],int left, int right, int x){
if(left>right)return -1; → Điều kiện dừng nếu không nằm trong mảng
else{
int mid = (left+right)/2; → Tìm vị trí ở giữa đoạn cần tìm
if(arr[mid]==x)return mid; → Điều kiện dừng khi tìm thấy k
elseif(arr[mid]<x)return Timkiemnp(arr,mid+1,right,x)
else return Timkiemnp(arr,left,mid+1,x) → Điều kiện để giới hạn đoạn cần tìm
}
}

You might also like