1. Trang chủ
  2. » Giáo Dục - Đào Tạo

Bài giảng cấu trúc dữ liệu và giải thuật – bài 12 khử đệ quy

27 2 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Cấu trúc liệu giải thuật Bài 12 Khử đệ quy Giảng viên: TS Ngo Huu Phuc Tel: 0438 326 077 Mob: 098 5696 580 Email: ngohuuphuc76@gmail.com @copyright by PhD Ngo Huu Phuc, Le Quy Don Technical University Bài 12 Khử đệ quy Nội dung học: 12.1 Khái niệm chung 12.2 Khử đệ quy cho toán tính giai thừa 12.3 Khử đệ quy cho tốn Fibonacci 12.4 Khử đệ quy cho toán tháp Hanoi 12.5 Khử đệ quy cho toán QuickSort Tham khảo: Data structures and Algorithms Stacks.htm Kyle Loudon Mastering Algorithms, Chapter Stacks and Queues Elliz Horowitz – Fundamentals of Data Structures, Chapter Stacks and Queues Deshpande Kakle – C and Data Structures, Chapter 19 Stacks and Queues Bài giảng TS Nguyễn Nam Hồng @copyright by PhD Ngo Huu Phuc, Le Quy Don Technical University 12.1 Khái niệm chung (1/7) Đối với hệ điều hành, thơng thường, chương trình gọi, thực hiện: Trước hết, hệ điều hành lưu tất thông tin cần thiết chương trình (thơng tin cần thiết) Tiếp theo, chuẩn bị gọi chương trình chuyển quyền điều khiển cho chương trình Sau đó, kết thúc chương trình con, hệ điều hành lấy lại thơng tin lưu bước chuyển quyền điều khiển đến nơi gọi chương trình Lưu ý: thơng tin lưu Stack chương trình @copyright by PhD Ngo Huu Phuc, Le Quy Don Technical University 12.1 Khái niệm chung (2/7) Stack chương trình:  Đối với ngôn ngữ bậc cao, sử dụng Stack chương trình cho lời gọi chương trình  Như vậy, chương trình gọi, thơng tin mơi trường (tại nơi gọi chương trình con) đưa vào stack chương trình  Khi quay trở lại nơi gọi chương trình con, thơng tin lấy lại từ stack chương trình  Với cách này, nhớ cần thiết lớn áp dụng cho toán đệ quy @copyright by PhD Ngo Huu Phuc, Le Quy Don Technical University 12.1 Khái niệm chung (3/7) Sử dụng ghi dạng stack riêng:  Một phương pháp đơn giản để kiểm sốt nhớ lời gọi chương trình con, sử dụng stack riêng để lưu biến, địa cần thiết  Về mặt chất, gần giống với hệ thống, nhiên lưu trữ thông tin cần thiết (khơng phải tồn thơng tin trước lời gọi chương trình con)  Quá trình lưu lấy lại tương tự thao tác stack @copyright by PhD Ngo Huu Phuc, Le Quy Don Technical University 12.1 Khái niệm chung (4/7) Với cách sử dụng Stack riêng, lưu ý:  Sử dụng biến để lưu địa nơi gọi chương trình  Với tham số dạng giá trị, tạo copy lưu  Với biến dạng tham chiếu, lưu trữ địa chúng  Với biến cục (khai báo đoạn chương trình), tạo copy lưu chúng @copyright by PhD Ngo Huu Phuc, Le Quy Don Technical University 12.1 Khái niệm chung (5/7) Các bước gợi ý việc khử đệ quy tổng quát: Có thể tạo stack riêng để chứa ghi Lệnh gọi đệ quy lệnh trả từ hàm đệ quy thay sau:  Đưa vào stack ghi chứa biến cục bộ, tham số vị trí dịng lệnh sau lệnh gọi đệ quy  Gán tham số trị thích hợp  Trở thực dòng lệnh giải thuật đệ quy  Mỗi lệnh trả hàm đệ quy thay đổi:  Lấy lại từ stack để phục hồi biến, tham số  Bắt đầu thực dịng lệnh vị trí mà trước cất stack @copyright by PhD Ngo Huu Phuc, Le Quy Don Technical University 12.1 Khái niệm chung (6/7) Các bước gợi ý việc khử đệ quy đuôi: Sử dụng biến để thay cho việc gọi đệ quy Sử dụng vòng lặp với điều kiện kết thúc giống điều kiện dừng đệ quy Đặt tất lệnh vốn cần thực lần gọi đệ quy đuôi vào vòng lặp Thay lệnh gọi đệ quy phép gán Dùng lệnh gán để gán trị tham số mà hàm đệ quy lẽ nhận Trả trị cho biến định nghĩa bước @copyright by PhD Ngo Huu Phuc, Le Quy Don Technical University 12.1 Khái niệm chung (7/7) Một số lưu ý sử dụng:  Nếu tất tham số có kiểu:  Sử dụng nhiều thao tác push vào stack  Sau đó, sử dụng nhiều thao tác pop để phục hồi thông tin  Nếu tham số có kiểu khác nhau:  Sử dụng cấu trúc hoặc,  Sử dụng nhiều stack cho loại tham số @copyright by PhD Ngo Huu Phuc, Le Quy Don Technical University 12.2 Khử đệ quy cho tốn tính giai thừa(1/4) Xét lại đoạn chương trình tính n! long factorial(int n) { if((n==0)||(n==1)) return 1; else return n*factorial(n-1); } 10 @copyright by PhD Ngo Huu Phuc, Le Quy Don Technical University 12.2 Khử đệ quy cho tốn tính giai thừa(4/4) Thực hàm nonFactorial (4) nonN = 4; stack.push(4); nonN=4-1=3; stack.push(3); nonN=3-1=2; stack.push(2); nonN=2-1=1; factorial = 1; stack.pop(&nonN); nonN=2; factorial = 2*1 = 2; stack.pop(&nonN); nonN=3; factorial = 2*3 = 6; stack.pop(&nonN); nonN=4; factorial = 6*4 = 24; 13 @copyright by PhD Ngo Huu Phuc, Le Quy Don Technical University 12.3 Khử đệ quy cho tốn Fibonacci (1/4) Phân tích lại tốn tính Fibonaccy đi: long fibonacci(int n, int a, int b) { if(n==1) return b; else return fibonacci(n-1,b,a+b); } Lời gọi hàm tương ứng, ví dụ: printf("Fibonacci cua %d: %ld",n,fibonacci(n,0,1)); 14 @copyright by PhD Ngo Huu Phuc, Le Quy Don Technical University 12.3 Khử đệ quy cho tốn Fibonacci (2/4)  Trong ví dụ trên, phần đệ quy gọi lại lần, bước để khử đệ quy, dùng sau:  Sử dụng Stack để lưu giá trị động nonN  Làm rỗng Stack  Sử dụng vòng lặp để đưa nonN vào Stack  Sử dụng vòng lặp thứ để lấy giá trị từ Stack thực phép cộng  Lưu ý, địa lưu vị trí dịng lệnh gọi đặt phép cộng 15 @copyright by PhD Ngo Huu Phuc, Le Quy Don Technical University 12.3 Khử đệ quy cho tốn Fibonacci (3/4) #include "conio.h" long nonFibonaccy(int n) { #include "stdio.h" StackClass stack; #define MaxEntry 100 if(n==1) return 1; #include "StackClass.h" else { int nonN=n; long nonFibonaccy(int n); void main() while(nonN>1) { stack.push(nonN); nonN ; } { int n; long fibonaccy=0; printf("Nhap vao mot so: "); int a=0,b=1; scanf("%d",&n); while(!stack.isEmpty()) { printf("Gia tri fibonaccy cua %d la: %ld",n,nonFibonaccy(n)); getch(); stack.pop(&nonN); fibonaccy=a+b; a=b; } b=fibonaccy; } return fibonaccy; } 16 } PhD Ngo Huu Phuc, Le Quy Don Technical University 12.3 Khử đệ quy cho tốn Fibonacci (4/4) Thực hàm nonFibonacci(4) nonN = 4; stack.push(4); nonN=4-1=3; stack.push(3); nonN=3-1=2; stack.push(2); nonN=2-1=1; fibonacci = 0; a = 0; b = 1; stack.pop(&nonN); fibonacci=0+1=1; a=1; b=1; stack.pop(&nonN); fibonacci=1+1=2; a=1; b=2; stack.pop(&nonN); fibonacci=1+2=3; a=2; b=3; 17 @copyright by PhD Ngo Huu Phuc, Le Quy Don Technical University 12.4 Khử đệ quy cho toán QuickSort (1/6) void qsort(int list[],int m,int n) { int key,i,j,k; if( m < n) { k = getkeyposition(m,n); swap(&list[m],&list[k]); while(i

Ngày đăng: 26/12/2021, 17:19

Xem thêm: