Recursive Programming - มหาวิทยาลัยบูรพา วิทยาเขตจันทบุรี

Download Report

Transcript Recursive Programming - มหาวิทยาลัยบูรพา วิทยาเขตจันทบุรี

290210 Data Structures and Algorithms
การเรียกซา้ (Recursion)
อ.ธารารัตน์ พวงสุวรรณ
ิ ปศาสตร์
คณะวิทยาศาสตร์และศล
มหาวิทยาลัยบูรพา วิทยาเขตสารสนเทศจันทบุรี
[email protected]
การเรียกซา้ (Recursion)



้
เป็ นการนิ ยามการแก ้ปัญหาด ้วยขันตอนวิ
ธี
แบบวนซา้ (Repetition Algorithm) โดยมี
การเรียกใช ้งานตัวมันเอง (Call itself)
เรียกการเขียนโปรแกรมในลักษณะเรียกใช ้งาน
ตัวเองว่า Recursive Programming
่ ั มี
่ การเรียกใช ้งานตัวมันเองว่า
เรียกฟังก ์ชนที
Recursive Function
Approach to writing
Repetition Algorithms
มี 2 Approach คือ
 Use Iteration
 Use Recursion
Recursion is a repetitive process in
which an algorithm calls itself
 Some older languages do not support
recursion

Recursive Function
ฟังก ์ชันเรียกตนเอง จะทางานได ้อย่างสมบูรณ์ จะต ้องมี
องค ์ประกอบ ดังต่อไปนี ้


่ ชอเป็
่ งก ์ชันของตนเอง เช่น
มีการเรียกใช ้ฟังก ์ชันทีมี
ื่ นชือฟั
่
ชือของตนคื
อ factorial ก็จะมีการเรียกใช ้ฟังก ์ชัน
่
่ อเป็ น
factorial() ภายในซึงอาจจะอยู
ใ่ นส่วนคาสังหรื
องค ์ประกอบในนิ พจน์
มีการร ับค่าเข ้าทางพารามิเตอร ์ของฟังก ์ชัน โดยค่าดังกล่าว
่
จะถูกนาไปใช ้ภายในฟังก ์ชันเอง ซึงผลของการค
านวณ
่ การเรียกใช ้”ชือ”ฟั
่
บางส่วนจะถูกนาไปใช ้เวลาทีมี
งก ์ชันตนเอง
Recursive Function


่
มีการส่งผลการคานวณกลับ ซึงผลดั
งกล่าวจะนาไปใช ้ใน
การคานวณในฟังก ์ชันเรียกตนเองหรืออาจจะส่งกลับใหก้ บ
ั
โปรแกรม
้ ดของการเรียกตนเอง ฟังก ์ชัน เรียกตนเองจะ
มีจด
ุ สินสุ
ทางานไม่ได ้หากไม่มช
ี อ่ งทางให ้โปรแกรมหยุดการเรียกตนเอง
้ ใดขันหนึ
้
่ ง เพราะจะเกิดการเรียกตนเองแบบไม่มส
ในขัน
ี นสุ
ิ้ ด
Recursive Programming
่
บางปัญหาสามารถทีจะเขี
ยนในรูปแบบของ recursion จะง่ายก
หลักการแก ้ปัญหาในรูปแบบ recursion
1. นิ ยามปัญหาในรูปการเรียกตัวเอง
่
2. มีเงือนไขส
าหร ับจบการทางาน

“One important requirement for a recursive alg
correct is that it not generate an infinite sequenc
ลักษณะของ Recursive
function


call itself directly
call itself indirectly หรือเรียกว่า
Recursive chains
Recursive Programming
ตัวอย่าง
S(n) = 1+2+3+4+5+6+7+…+n
S(1) = 1
S(2) = 1+2 = S(1)+2
S(3) = 1+2 +3 = S(1)+2+3 =
S(2)+3
จะได้
S(n) = S(n-1)+n
Recursive Programming
่ ควรทา
ตัวอย่าง recursive function ทีไม่
int main(void) {
printf(“The universe is never ending\n”);
main();
return 0;
} //an infinite sequence of call on itself
Recursive chains
ตัวอย่างของ Recursive chains
a(formal parameters)
b(formal
parameters)
{
{
.
.
.
.
.
.
b(arguments);
a(arguments);
} /* end a */
} /* end b
“Both a and b are recursive”
*/
A Classic Recursive Case


Factorial เป็ น case study
Factorial(n) =
1
if n=0
2x1
if n >0
n x (n-1) x (n-2) x ... x 3 x
Iterative Factorial Algorithm
Algorithm iterativeFactorial (n)
Calculates the factorial of a number using a loop
Pre
n is the number to be raised factoriallly
Post
n! is returned
Return factN เป็ นค่า n!
1
set i to 1
2
set factN to 1
3 loop( i <= n)
1
set factN to factN * i
2
increment i
4 end loop
5 return factN
end iterativeFactorial
Recursive Factorial
Algorithm
Algorithm recursiveFactorial (n)
Calculates factorial of a number using recursion
Pre
n is the number to be raised factoriallly
Post
n! is returned
Return ค่า n!
1
if (n equal 0)
1
return 1
2 else
1
return (n * recursiveFactorial (n-1))
3 end if
end recursiveFactorial
การคานวณหาค่าแฟกทอเรียล
ของจานวนเต็มบวก
การนิยามแบบ iterative
n! = n * (n-1) * (n-2) * ... 1
ั ได ้ว่า
อาจเขียนคาจากัดความของฟั งก์ชน
n! = 1
if n ==0
n! = n * (n-1) * (n-2) * ... * 1 if n > 0
Iterative programming
//Function for calculating factorial of integer
long int fact(int n)
{
int x;
prod = 1;
for(x = n; x > 0; x--)
prod = prod * x;
return(prod);
}
การนิ ยามแบบ Recursion
1. เขียนปัญหาในรูปการเรียกตัวเอง
n! = n * (n-1)!
อาจเขียนคาจากัดความของฟังก ์ช ัน ได ้ว่า
n! = 1 if n ==0
n! = n * (n-1)! if n > 0
่
2. หาเงือนไขส
าหร ับจบการทางาน
่ ยกตัวเองจนถึง 0! = 1
คือ เมือเรี
Recursive programming
//Function for calculating factorial of integer
long int fact(int n)
{
if(n == 0)
//condition for end calling
return(1)
else
Recursion
return(n * fact(n-1));
}
Recursive
่ บก ันกบ
programming
“Recursive
function จะทางานในลาดับทีกลั
ั เ
จากโปรแกรมหาค่าแฟกทอเรียลแบบ recursion การเรียกใช ้จะ
n! = n * (n-1)!
(n-1)! = (n-1) * (n-2)!
(n-2)! = (n-2) * (n-3)!
.........
2! = 2 * 1!
1! = 1 * 0!
0! = 1
Recursive
programming
่ งกลับมาจะเป็ นลาดับทีกลั
่ บกัน
ค่าทีส่
0!
1!
2!
3!
4!
=1
= 1 * 0! = 1
= 2 * 1! = 2 * 1 = 2
= 3 * 2! = 3 * 2 = 6
= 4 * 3! = 4 * 6 = 24
........
n! = n * (n-1)! = ......
ดังนี ้
Recursive
programming
ดังนั้น ส่ง 4 เข ้าไปให ้ฟังก ์ชัน
return(4 *
พอเรียกฟังก ์ชัน จะได ้
return(3 *
return(2 *
return(1 *
return(1);
จะเห็นว่า
ค่าส่งกลับจะเป็ น return(4*3*2*1*1)
Recursive Example

เป็ นตัวอย่างของการแก ้ปัญหาแบบ
Recursion
 Greatest Common Divisor (GCD)
 Fibonacci Numbers
 Towers of Hanoi
Greatest Common
Division(GCD)





เป็ นฟังก ์ช ันทางคณิ ตศาสตร ์ ทีรู่ ้จักกันว่า การหา
ตัวหารร่วมมาก (ห.ร.ม.)
่ เป็ น 0 พร ้อมกัน คือ
gcd ของจานวนเต็มซึงไม่
่
่ ดทีหารทั
่
้
จานวนเต็มทีมากที
สุ
งสองจ
านวนลงตัว
เช่น gcd ของ 10 กับ 25 คือ 5
มีประโยชน์ในการทาเศษส่วนให ้เป็ นเศษส่วนอย่าง
ตา่
ใช ้ Euclidean Algorithm ในการหา gcd ของ
่ เป็ นค่าลบ
จานวนเต็มทีไม่
Greatest Common
Division(GCD)

gcd (a,b) =
b=0
0
a
b
gcd (b, a mod b)
otherwise
if
if a =
Greatest Common
Division(GCD)
Algorithm gcd (a, b)
Calculates greatest common division using the
Euclidean algorithm
Pre a and b are positive integers greater than 0
Post greatest common divisor returned
..............................................
...............................................
.................................................
.................................................
..................................................
..................................................
.................................................
end gcd
การหา Fibonacci numbers
การหาชุดของ Fabonacci series จะต ้องทราบ
ตัวเลข 2 ตัวแรก
นิ ยาม

Fib(n) = n
if n = 0 or n = 1
Fib(n) = Fib(n-1) + Fib(n-2) if n > 1
Fibonacci numbers
เขียนเป็ น recursive function ได ้ว่า
int fib(int n) {
int x,y;
if(n<= 1)
return(n);
x = fib(n-1);
y = fib(n-2);
return(x+y);
}
Tower of Hanoi Problem
A
B
C
เป้ าหมาย
่
้
ต ้องการเคลือนย
้าย disk ทังหมดไปไว
้อีก peg หนึ่ ง
ข้อกาหนด
่
้ั 1 disk เท่านั้นโดยเคลือนย
่
- เคลือนย
้ายครงละ
้ายจาก disk บ
่
่ กกว่า
- ไม่อนุ ญาตให ้ disk ทีใหญ่
กว่าซ ้อนบน disk ทีเล็
่
้
จากรูปดังกล่าว หากเราต ้องการเคลือนย
้าย disk ทังหมดจา
Recursive solution for Towers of Hanoi Problem
1.
if n==1, move the single disk from A to C and stop
2. Move the top n-1 disks from A to B, using C as auxiliary
3. Move the remaining disk from A to C
4. Move the n-1 disks from B to C, using A as auxiliary
Efficiency of recursion
่
่ ลก
โดยทัวไป
โปรแกรมทีมี
ั ษณะ nonrecursive การประมวล
่ ลก
ประสิทธิภาพดีกว่าโปรแกรมทีมี
ั ษณะ recursive ในด ้านของเว
่
หน่ วยความจา (space) แต่ลก
ั ษณะบางโปรแกรมก็เหมาะทีจะเขี
ยน
เพราะจะทาให ้ง่ายกว่าและเกิดข ้อผิดพลาดได ้น้อยกว่าแบบ nonr
ข้อดีของ recursive programming
้ ง่าย
- เขียนได ้สัน
- มองเห็นแนวทางการแก ้ปัญหาได ้ช ัดเจน
- ใช ้เวลาไม่มากในการเขียนโปรแกรม
ข้อเสียของ recursive programmi
่
บางปัญหาไม่เหมาะทีจะแก
้ปัญหาด ้วย recursive programmi
่ าซ
้ ้อน
จากทาให ้มีการทางานทีซ
เช่น การหา Fibonacci number
Fib(n) = n
if n = 0 or n = 1
Fib(n) = Fib(n-1) + Fib(n-2) if n > 1
ตัวอย่าง
Fib(5) = Fib(4) + Fib(3)
Fib(4) = Fib(3) + Fib(2)
Fib(3) = Fib(2) + Fib(1)
Fib(2) = Fib(1) + Fib(0)