• Viết chương trình nhập 1 mảng số int, nhập 1 trị x, tìm vị trí có x cuối cùng trong mảng. Dùng kỹ thuật đệ quy để tìm vị trí này[r]
(1)CHƯƠNG 7
(2)Mục tiêu
Đến cuối chương, bạn có thể:
• Giải thích giải thuật đệ quy
• Biết cách diễn đạt tác vụ hướng đệ quy • Biết cách thực hàm đệ quy
• Phân loại loại đệ quy
(3)Ơn tập
• Stack: Cấu trúc (thường mảng) có chế xử lý: vào sau trước
• Queue: Cấu trúc (thường mảng) có chế xử lý: vào trước trước
• Stack Queue gọi danh sách hạn chế
(4)7.1- Đệ quy (Recursion)
• Định nghĩa tường minh: Giải thích khái niệm khái niệm có • Người = Động vật cấp cao
• Định nghĩa lịng vịng: Giải thích khái niệm khái niệm
• Đệ quy: Đưa ra định nghĩa có sử dụng khái niệm cần định
(5)Đệ quy gì?
• Con người hiểu định nghĩa đệ quy đệ quy có chặn (điều kiện biên, điều kiện suy biến) – biên ngầm định
• Người = hai người khác Ngầm
hiểu có người
• Thư mục = thư mục + tập tin
Ngầm hiểu: Hiển nhiên tồn thư mục
(6)7.2- Kiểu liệu đệ quy
• Một người mô tả bằng: tên, năm sinh, cha (một người khác), mẹ (một người khác)
struct NGUOI { char Ten[51]; int namsinh; NGUOI cha; NGUOI me;
Cấu trúc khơng khả thi máy tính
(7)Kiểu liệu đệ quy
• Sửa lại:
struct NGUOI { char Ten[51]; int namsinh;
NGUOI* pCha; NGUOI* pMe; };
NGUOI x;
Ten (51 bytes) namsinh (2 bytes)
pCha (4 bytes) pMe (4 butes)
(8)7.3- Tác vụ đệ quy
• Có thể diễn đạt nhiều tác vụ hướng đệ quy • 1+2+3+ + (n-2) + (n-1) + n
• Cộng( tới n) = n + Cộng (1 tới n-1)
• Điều kiện biên điều kiện ngưng khơng đệ quy • Điều kiện biên: Cộng (1 tới 1)
• Cộng (1 tới n) = 1, n=1
(9)7.4- Cách viết hàm đệ quy
• Định nghĩa tác vụ đệ quy theo ngơn ngữ tự nhiên hàm viết
• Thí dụ: n! = 1*2*3*4*5* * n n! = 1, n<=1
(10)Cách viết hàm đệ quy
n! = 1, n<=1 n* (n-1)!
Điều kiện biên
2 dòng
(11)Luyện tập viết hàm đệ quy
• Tìm trị phần tử thứ n cấp số cộng có số hạng đầu a, công sai r
Un = a, n=1
r + Un-1
• Tìm trị phần tử thứ n cấp số nhân có số hạng đầu a, cơng bội q
Un = a, n=1
q*U
(12)Luyện tập viết hàm đệ quy
• Xuất biểu diễn nhị phân số nguyên dương
13 1101
Dạng nhị phân của (13/2)
13%2
Xuất dạng nhị phân n: Nếu (n>=0)
{ Nếu (n/2>0) Xuất dạng nhị phân n/2; Xuất (n%2);
}
(13)Luyện tập viết hàm đệ quy
(14)7.5- Phân loại hàm đệ quy
• Tùy thuộc cách diễn đạt tác vụ đệ quy mà có loại đệ quy sau
(15)7.7.1-Đệ quy tuyến tính
• Thân hàm gọi lần nó
• Un = a , n=1 ( trị thứ n cấp số cộng)
r + Un-1 , n>1
double U (int n, double a, double r) { if (n==1) return a;
(16)7.5.2-Đệ quy nhị phân
• Thân hàm gọi lần
• Chuỗi số Fibonacci: 1 13 • Un = 1, n=1,2
Un-2 + Un-1 , n>2
long Fibo (int n)
{ if (n<=2) return 1;
(17)7.5.3-Đệ quy phi tuyến
• Thân hàm lặp gọi số lần
• Un = n , n <6
Un-5 + Un-4 + Un-3 + Un-2 + Un-1 ,n >6
long U ( int n)
{ if (n<6) return n; long S= 0;
for (int i = 5; i>0; i ) S+= U(n-i); return S;
(18)7.5.4-Đệ quy hỗ tương
• 2 hàm đệ quy gọi nhau
• Un = n , n<5
Un-1 + Gn-2 , n>=5
• Gn = n-3 , n<8
Un-1 + Gn-2 , n>8
long G(int n); long U ( int n)
{ if (n<5) return n;
return U(n-1) + G(n-2); }
long G(int n)
{ if (n<8) return n-3;
(19)7.6- Kỹ thuật tìm giải thuật đệ quy
• Thơng số hóa tốn
• Tìm điều kiện biên(chặn), tìm giải thuật cho tình
(20)Tính tổng mảng a, n phần tử • Thơng số hóa: int*a, int n
• Điều kiện biên: Mảng phần tử tổng • Giải thuật chung:
Sum(a,n) = a[0] + a[1] + a[2] + + a[n-2] +a[n-1] Sum(a,n-1)
Sum (a,n) = , n=0
a[n-1] + Sum(a, n-1)
• Với thuật tốn đệ quy mảng, ta nên giảm dần
(21)Tìm trị lớn mảng a, n phần tử
• Thơng số hóa: int*a, int n
• Điều kiện biên: Mảng phần tử trị lớn a[0] • Giải thuật chung:
Max(a,n) = a[0] , a[1] , a[2] , , a[n-2] , a[n-1] Max(a,n-1)
Max (a,n) = a[0] , n=1
a[n-1] > Max(a, n-1)? a[n-1] : Max(a,n-1) • Thuật tốn đệ quy tìm trị nhỏ mảng?
(22)Xuất ngược chuỗi
• S= “QWERT” TREWQ
Ký tự đầu của S Kết qủa xuất ngược
chuỗi &S[1]
Xuất_ngược (S) : L= strlen(S);
if (L>1) Xuất_ngược (S+1); if (L) Xuất (*S);
(23)(24)7.7- Bài toán Tháp Hà Nội
(25)Bài tốn Tháp Hà Nội
Xem cách phân tích mã hóa tốn tốn tài liệu tham khảo
Chuyển n đĩa từ cột X sang cột Z nhờ cột
trung gian Y
(1) Chuyển n-1 đĩa từ cột X sang cột Y nhờ cột trung gian Z đĩa bên đĩa nhỏ.
(2) Chuyển đĩa n (to nhất) từ cột X sang cột đích Z.
(26)Tháp Hà Nội
3 2 1
3 2 1
3 2
1
(27)7.8- Cách thực thi hàm đệ quy
• Xét hàm tính giai thừa
n: 5 Kq
n: 4 Kq
n: 3 Kq
n: 2 Kq
(28)Cách thực thi hàm đệ quy
• Xét hàm tính giai thừa
n: 5 Kq:
n: 4 Kq:
n: 3 Kq:
n: 2 Kq:
(29)Cách thực thi hàm đệ quy
• Xét hàm tính giai thừa
n: 5 Kq: n: 4 Kq: n: 3 Kq: n: 2 Kq: n: 1 Kq 1
(30)Cách thực thi hàm đệ quy
• Xét hàm tính giai thừa
n: 5 Kq:
n: 4 Kq:
n: 3 Kq:
n: 2 Kq:
(31)Cách thực thi hàm đệ quy
• Xét hàm tính giai thừa
n: 5 Kq:
n: 4 Kq:
n: 3 Kq: 6
(32)Cách thực thi hàm đệ quy
• Xét hàm tính giai thừa
n: 5 Kq:
n: 4 Kq: 24
n: 5
(33)Cách thực thi hàm đệ quy
• Xét hàm tính giai thừa
(34)7.9- Nhận xét hàm đệ quy
HÀM ĐỆ QUY: Vừa tốn nhớ vừa chạy chậm
Giải thuật đệ quy đẹp (gọn gàng), dễ chuyển thành chương trình.
Nhiều ngơn ngữ không hỗ trợ giải thuật đệ quy (Fortran).
(35)7.10- Khử đệ quy
• Là trình chuyển đổi giải thuật đệ quy
thành giải thuật khơng đệ quy
• Chưa có giải pháp cho việc chuyển đổi
một cách tổng quát
• Cách tiếp cận:
(1) Dùng quan điểm đệ quy để tìm giải thuật cho tốn
(2) Mã hóa giải thuật đệ quy
(36)7.10.1- Khử đệ quy vịng lặp
• Ý tưởng: Lưu lại trị lần tính tốn
(37)Thí dụ: Hàm tính giai thừa n
long GiaiThua( int n) { if (n<2) return 1;
return n * GiaiThua(n-1); }
Trị cần lưu
long GiaiThua( int n) { long K=1;
for (int i =2; i<=n;i++) K=K*i; return K;
}
Điều kiện biên
(38)Thí dụ hàm tính trị thứ n dãy Fibonacci:
1
long Fibo(int n)
{ if (n<=2) return 1; // hai chặn return Fibo(n-2) + Fibo (n-1);
} 1t 2t
t3=t1+t 2
t1 t2 t3
t1 t2 t3
t1 t2 t3
long Fibo(int n)
{ if (n<=2) return 1; // hai chặn long t1=1, t2=1;
for (int i=3; i<=n;i++) { t3=t1+t2;
t1=t2; t2= t3; }
(39)7.10.2- Khử đệ quy stack
• Khởi tạo stack với số phần tử phù hợp • Đưa tham số đầu vào stack
• Khi Stack không trống
{ - Lấy tham số khỏi stack;
- Xử lý tác vụ ứng với tham
số Nếu gặp tác vụ đệ quy lại đưa
tham số tác vụ đệ quy tương ứng vào stack
(40)Bài toán tháp Hà Nội khử-đệ quy
(41)Tóm tắt
• Hàm đệ quy hàm mà thân hàm lại gọi
• Hàm đệ quy hiệu qủa vì: tốn nhớ va gọi hàm qúa nhiều lần Tuy nhiên viết hàm đệ quy ngắn gọn
(42)Bài tập
• Viết chương trình xuất n trị cấp số cộng có số hạng đầu a (nhập từ bàn phím), cơng sai r
(nhập từ bàn phím) Sử dụng kỹ thuật đệ quy để xây dựng hàm tính trị thứ i cấp số cộng
• Dùng kỹ thuật đệ quy để giải phương trình f(x) khoảng [a,b] với sai số epsilon
• Gọi px pointer nghiệm
if (f(a).f(b)>0) return NULL (khơng có nghiệm) else if (b-a <= epsilon) return &a;
else
{ c=(b+a)/2) ;
(43)Bài tập
• Viết chương trình nhập mảng số int, nhập trị x, tìm vị trí có x cuối mảng Dùng kỹ thuật đệ quy để tìm vị trí này. Tìm x a[], n : -1 n<0
n-1 a[n-1]=x Tìm x a, n-1
• Viết chương trình nhập ma trận vuông số int , nhập trị x Tìm vị trí <dịng,cột> có x dùng kỹ thuật đệ quy.
Tìm vị trí có x ma trận m,n
NULL, n<1