C9: Đệ qui

27
C9: Đệ qui 1. Định nghĩa 2. Phân loại 3. Chú ý khi viết hàm

description

C9: Đệ qui. 1. Định nghĩa 2. Phân loại 3. Chú ý khi viết hàm. 1. Định nghĩa. - PowerPoint PPT Presentation

Transcript of C9: Đệ qui

Page 1: C9: Đệ qui

C9: Đệ qui

1. Định nghĩa

2. Phân loại

3. Chú ý khi viết hàm

Page 2: C9: Đệ qui

1. Định nghĩa

• Trong toán học và khoa học máy tính, các tính chất (hoặc cấu trúc) được gọi là đệ quy nếu trong đó một lớp các đối tượng hoặc phương pháp được xác định bằng việc xác định một số rất ít các trường hợp hoặc phương pháp đơn giản (thông thường chỉ một) và sau đó xác định quy tắc đưa các trường hợp phức tạp về các trường hợp đơn giản

Page 3: C9: Đệ qui

Ví dụ

Chẳng hạn, định nghĩa sau là định nghĩa đệ quy của tổ tiên:

•Bố mẹ của một người là tổ tiên của người ấy (trường hợp cơ bản);

•Bố mẹ của tổ tiên một người bất kỳ là tổ tiên của người ấy (bước đệ quy)

Page 4: C9: Đệ qui

1. Định nghĩa đệ qui

Một khái niệm X được định nghĩa theo đệ quy nếu trong định nghĩa X có sử dụng ngay chính khái niệm X

Page 5: C9: Đệ qui

Ví dụ 1: Định nghĩa Số tự nhiên

- 0 là một số tự nhiên

- n là số tự nhiên nếu n - 1 là số tự nhiên

Page 6: C9: Đệ qui

Ví dụ 2: Định nghĩa Hàm giai thừa n!

0! = 1

Nếu n > 0 thì n! = n(n - 1)!

0 giai thừa = 1

Nếu n > 0 thì

n giai thừa = n(n - 1) giai thừa

Page 7: C9: Đệ qui

Đệ quy trong khoa học máy tính

Có một phương pháp chung để giải các bài toán đệ quy là chia bài toán thành các bài toán con đơn giản hơn cùng loại.

Phương pháp này được gọi là kỹ thuật lập trình chia để trị.

Là chìa khóa để thiết kế nhiều giải thuật quan trọng, là cơ sở của quy hoạch động.

Page 8: C9: Đệ qui

Trò chơi Tháp Hà Nội ???

• Trò chơi Tháp Hà Nội có thể đã xuất hiện ở Đông Á từ thế kỷ 19 hoặc trước đó. Các đĩa được làm bằng sứ ở Trung Quốc, Nhật Bản và Việt Nam.

• Trò chơi này được đưa sang phương Tây lần đầu bởi nhà toán học người Pháp Edouard Lucas vào năm 1883.

• Trò chơi này nhanh chóng được các nhà toán học nghiên cứu sau đó, và trở thành ví dụ về phương pháp giải đệ quy kinh điển trong dạy học và tin học. Lời giải cho trò chơi có thể tìm thấy chính xác cho trường hợp 3 cọc. Nhưng khi mở rộng cho 4 cọc hoặc nhiều hơn, lời giải chính xác cho đến này vẫn chưa được khẳng định.

Page 9: C9: Đệ qui

Bài toán tháp Hà Nội

Người chơi được cho ba cái cọc và một số (3) đĩa có kích thước khác nhau có thể cho vào các cọc này. Ban đầu sắp xếp các đĩa theo trật tự kích thước vào một cọc sao cho đĩa nhỏ nhất nằm trên cùng, tức là tạo ra một dạng hình nón. Người chơi phải di chuyển toàn bộ số đĩa sang một cọc khác, tuân theo các quy tắc sau:

– một lần chỉ được di chuyển một đĩa

– một đĩa chỉ có thể được đặt lên một đĩa lớn hơn (không nhất thiết hai đĩa này phải có kích thước liền kề, tức là đĩa nhỏ nhất có thể nằm trên đĩa lớn nhất)

Page 10: C9: Đệ qui

Mô hình của bài toán

Page 11: C9: Đệ qui

Thuật giải đệ quy

1.Đặt tên các cọc là A, B, C -- những tên này có thể chuyển ở các bước khác nhau

2.gọi n là tổng số đĩa

3.đánh số đĩa từ 1 (nhỏ nhất, trên cùng) đến n (lớn nhất, dưới cùng)

Để chuyển n đĩa từ cọc A sang cọc B thì cần:

1.chuyển n-1 đĩa từ A sang C. Chỉ còn lại đĩa n trên cọc A

2.chuyển đĩa n từ A sang B

3.chuyển n-1 đĩa từ C sang B cho chúng nằm trên đĩa n

Page 12: C9: Đệ qui
Page 13: C9: Đệ qui

Mô phỏng (3 đĩa)

Page 14: C9: Đệ qui

Mô phỏng (4 đĩa)

Page 15: C9: Đệ qui

2. Phân loại

• Đệ qui tuyến tính

• Đệ qui nhị phân

• Đệ qui phi tuyến tính

• Đệ qui tương hỗ

Page 16: C9: Đệ qui

Đệ qui tuyến tính

• Chương trình con đệ quy tuyến tính là chương trình con đệ quy trực tiếp đơn giản nhất

KDL TênHàm(<Danh sách tham số>{

if (điều kiện dừng){….return<giá trị trả về>;}…TênHàm(<Danh sách tham số>);…

}

P≡ {nếu thõa <điều kiện dừng> thì thực hiện S;Ngược lại {Thực hiện *S; gọi P;}}

Với S, S* là các thao tác không đệ quy

Page 17: C9: Đệ qui

Ví dụ cổ điển của đệ quy là hàm giai thừa

#include <iostream.h> long factorial (long a){

if (a == 1) return (1);

return (a * factorial (a-1)); } 

void main (){

long i; cout << "Type a number: "; cin >> i; cout << "!" << i << " la " << factorial (i);

}

n * (n-1) * (n-2) * (n-3) ... * 1n!=

Page 18: C9: Đệ qui

Đệ quy nhị phân

• Chương trình con đệ quy nhị phân là chương trình con đệ quy trực tiếp có dạng:

P≡ {nếu thõa <điều kiện dừng> thì thực hiện S;Ngược lại { Thực hiện *S; gọi P; gọi P}}

Với S, S* là các thao tác không đệ quy

Page 19: C9: Đệ qui

KDL TênHàm(<Danh sách tham số>{

if (điều kiện dừng){….return<giá trị trả về>;}…TênHàm(<Danh sách tham số>;…TênHàm(<Danh sách tham số>;

}

Page 20: C9: Đệ qui

f(0)=f(1)=1f(n)=f(np1)+f(np2), n>1long int Fibonaci(int n){ if(n==0||n==1)

return1; return

(Fibonaci(n-1)+Fibonaci(n-2));}

Page 21: C9: Đệ qui

Đệ quy phi tuyến tính

• Chương trình con đệ quy phi tuyến tính là chương trình con đệ quy trực tiếp mà lời gọi đệ quy được thực hiện bên trong vòng lặp

P≡{ for giá trị đầu to giá trị cuối dothực hiện S;if thõa điều kiện dừng then thực hiện *Selse gọi P;

Với S, *S là các thao tác không đệ quy

Page 22: C9: Đệ qui

KDL TenHam(<Danhsáchthamsố>){ for(int i=1;i<=n;i++) { … if(<điều kiện dừng>) { … } else { … TenHam(<Danhsáchthamsố>); … } }}

Page 23: C9: Đệ qui

Đệ quy tương hỗ

KDL TenHam2(<Danh sách tham số>);KDL TenHam1(<Danh sách tham số>){ …TenHam2(<Danh sách tham số>);…}KDL TenHam2(<Danh sách tham số>){ …TenHam1(<Danh sách tham số>);…}

Page 24: C9: Đệ qui

3. Chú ý khi viết hàm đệ qui

• Hàm đệ quy phải có 2 phần:– Phần dừng– Phần đệ quy là phần gọi hàm hay định nghĩa.

• Đệ quy tốn bộ nhớ và làm cho tốc độ xử lý chậm.

Page 25: C9: Đệ qui

if ( trường hợp đặc biệt){

Trình bày cách giải bài toán }else /* Trường hợp tổng quát */{

Gọi đệ qui tới hàm ( đang viết ) với các giá trị khác của tham số}

Hàm đệ qui thường được xây dựng theo thuật toán sau :

Page 26: C9: Đệ qui

Tính tổng các số nguyên dương từ 1 đến N

• Nếu n=1 thì tong=1

• Ngược lại tong=n+tong(n-1)

Tong=0

for (i=1; i<=n; i++)

Tong=tong+i

Page 27: C9: Đệ qui

#include <iostream.h>#include <conio.h> long tong(long a){

if (a = 1) return(1); else return (a + tong(a-1));}int main (){

long i; cout << "Type a number: "; cin >> i;cout << "Tong tu 1 den " << i << " = " << tong(i);

getch();return 0;

}