Tải bản đầy đủ (.pdf) (10 trang)

Bài giảng Cấu trúc dữ liệu và giải thuật – Bài 3: Đệ quy (Recursion)

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (364.29 KB, 10 trang )

<span class='text_page_counter'>(1)</span><div class='page_container' data-page=1>

Lecturer: PhD. Ngo Huu Phuc


Tel: 0438 326 077


Mob: 098 5696 580



Email:



<b>C</b>

<b>ấu trúc dữ liệu và giải thuật</b>



</div>
<span class='text_page_counter'>(2)</span><div class='page_container' data-page=2>

Khái ni

ệm về đệ quy.



Ví d

ụ về đệ quy.



Đệ quy đi (Tail Recursion)



Bài toán tháp Hanoi.



<b>Tham kh</b>

<b>ảo:</b>



</div>
<span class='text_page_counter'>(3)</span><div class='page_container' data-page=3>

<b>3.1. Khái ni</b>

<b>ệm về đệ quy (1/6)</b>



V

ới phần lập trình viên, để giải quyết bài tốn lớn, có



th

ể sử dụng 1 q trình dạng đệ quy.



Ta nói m

ột đối tượng là đệ qui nếu đối tượng này bao



g

ồm chính nó như một bộ phận hoặc đối tượng được



</div>
<span class='text_page_counter'>(4)</span><div class='page_container' data-page=4>

nó.


 Trong tính tốn, để giải quyết vấn đề sử dụng hàm đệ quy



(hàm gọi chính nó với tham số thay đổi).


 Như vậy, hàm đệ quy là hàm gọi lại chính nó.


 Với mỗi bước, hàm thay đổi thông tin đầu vào và cho kết


</div>
<span class='text_page_counter'>(5)</span><div class='page_container' data-page=5>

<b>3.1. Khái ni</b>

<b>ệm về đệ quy (3/6)</b>



• Giả sử cần tính giai thừa của một số nguyên dương n.


• Giai thừa của n được viết: <b>n!</b>, tích các phần tử từ n đến 1.
• Ví dụ, 5! = (5)(4)(3)(2)(1).


• Có thể thực hiện tính giai thừa bằng vịng lặp thơng thường


để tính tích.


• Một cách tiếp cận khác, sử dụng đệ quy, khi đó cơng thức


tính giai thừa được viết dạng:


</div>
<span class='text_page_counter'>(6)</span><div class='page_container' data-page=6>

thừa nhỏ hơn.


• Như vậy, ta có <b>n! = n * (n – 1)!</b>.


• Ta xử lý <b>(n - 1)!</b> giống như <b>n!</b>, với tham số nhỏ hơn.
• Ta có, <b>(n - 1)! = (n – 1) * (n - 2)!</b>,


• Tương tự, <b>(n - 2)! = (n – 2) * (n - 3)!</b>, quá trình trên kết thúc


khi n=1.


• Với cách tiếp cận dạng đệ quy, có thể định nghĩa lại cách


</div>
<span class='text_page_counter'>(7)</span><div class='page_container' data-page=7>

<b>3.1. Khái ni</b>

<b>ệm về đệ quy (5/6)</b>



Có th

ể hình dung đệ quy qua 2 bước chính:



<b>quay xuôi </b>

(

<b>winding</b>

) và

<b>quay ngược </b>


(

<b>unwinding</b>

).



T

ại bước

<b>winding</b>

, l

ời giải bài tốn gọi lại chính


nó.



 Với bước winding, lời gọi chính nó dừng khi thỏa mãn


điều kiện dừng.


 Điều kiện dừng thông thường được định nghĩa là tại


bước đó đã đến bài tốn cơ sở, có thể giải trực tiếp
được.


 Với mỗi hàm đệ quy cần có ít nhất một điều kiện


</div>
<span class='text_page_counter'>(8)</span><div class='page_container' data-page=8>

được thực hiện, các bài toán nhỏ trên được xem



xét theo th

ứ tự ngược lại.



 Bước này dừng lại khi q trình đến bài tốn gốc. Q



</div>
<span class='text_page_counter'>(9)</span><div class='page_container' data-page=9>

<b>3.2. Ví d</b>

<b>ụ về đệ quy (1/6)</b>



<b>Bước Winding</b>


F(4) = 4 * F(3)
F(3) = 3 * F(2)
F(2) = 2 * F(1)
F(1) = 1


<b>Bước UnWinding</b>


F(4) = 4 * 6 = 24
F(3) = 3 * 2 = 6
F(2) = 2 * 1 = 2
F(1) = 1


<b>Ví dụ 1: Tính n!.</b>


F(n) = n* F(n-1) nếu n > 1


</div>
<span class='text_page_counter'>(10)</span><div class='page_container' data-page=10>

#include<conio.h>


long factorial(int);


void main()


{


int n;



printf("Nhap vao mot so: ");
scanf("%d",&n);


printf("Gia tri cua giai thua:
%ld",factorial(n));


getch();
}


if((n==0)||(n==1)) return 1;


else return n*factorial(n-1);


</div>

<!--links-->

×