Professional Documents
Culture Documents
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
}
}