15
04/01/57 Advance Computer Programming: .กิตตินันท์ น้อยมณี 1 ฟังกชันเรยกตัวเอง Advance Computer Programming รหัสวชา 32090207 . กิตตินันท์ น้ 1อยมณี 1 เนอหา 1. Introduction 2. Factorial 3. Tower of Hanoi 4. Binary Search . กิตตินันท์ น้ 1อยมณี 2 Introduction . กิตตินันท์ น้ 3อยมณี 3 Introduction การเรยกตัวเอง (Recursion) คอการทําซํารูปแบบ หน่ง เหมอนกับการวนรอบ (Loop) ขอด คอ ในบางโจทยปัญหาจะเขยนดวย Loop ยากมาก แตการใช Recursion จะงายกวา ขอเสย คอ Recursion ใชหนวยความจํา Stack ของ ระบบ ่งอาจจะไมพอใชงาน เรยกปัญหาลักษณะ นวStack Overflow . กิตตินันท์ น้ 1อยมณี 4

C Language - 09 ฟังก์ชันเรียกตัวเอง

  • Upload
    -

  • View
    41

  • Download
    4

Embed Size (px)

Citation preview

Page 1: C Language - 09 ฟังก์ชันเรียกตัวเอง

04/01/57

Advance Computer Programming: อ.กิตตนินัท์ น้อยมณี 1

ฟังก์ชันเรียกตัวเอง

Advance Computer Programming

รหัสวิชา 32090207

อ. กิตตินนัท์ น้1อยมณี 1

เนื้อหา

1. Introduction

2. Factorial

3. Tower of Hanoi

4. Binary Search

อ. กิตตินนัท์ น้1อยมณี 2

Introduction

อ. กิตตินนัท์ น้3อยมณี 3

Introduction

• การเรียกตัวเอง (Recursion) คือการทําซ้ํารูปแบบหนึ่ง เหมือนกับการวนรอบ (Loop)

• ข้อดี คือ ในบางโจทย์ปัญหาจะเขียนด้วย Loop ยากมาก แต่การใช้ Recursion จะง่ายกว่า

• ข้อเสีย คือ Recursion ใช้หน่วยความจํา Stack ของระบบ ซึ่งอาจจะไม่พอใช้งาน เรียกปัญหาลักษณะนี้ว่า Stack Overflow

อ. กิตตินนัท์ น้1อยมณี 4

Page 2: C Language - 09 ฟังก์ชันเรียกตัวเอง

04/01/57

Advance Computer Programming: อ.กิตตนินัท์ น้อยมณี 2

Factorial

อ. กิตตินนัท์ น้5อยมณี 5

Factorial

5! = 5 x 4 x 3 x 2 x 1 = 5 x 4!

4! = 4 x 3!

3! = 3 x 2!

2! = 2 x 1!

1! = 1

อ. กิตตินนัท์ น้1อยมณี 6

ขั้นตอนที่ 2 : เงื่อนไขการหยุดเรียกตัวเอง

ขั้นตอนที่ 1 : สูตรในการเรียกตัวเองคือ

n! = n x (n-1)!

Factorial

อ. กิตตินนัท์ น้1อยมณี 7

แบบวน Loop

Recursion

Factorial

อ. กิตตินนัท์ น้1อยมณี 8

Page 3: C Language - 09 ฟังก์ชันเรียกตัวเอง

04/01/57

Advance Computer Programming: อ.กิตตนินัท์ น้อยมณี 3

Factorial

• นี่คือหลักการทํางานของ Stack เลย นั่นคือ เข้า

ก่อน ออกหลัง (Last-In-First-Out: LIFO)

อ. กิตตินนัท์ น้1อยมณี 9

Factorial

อ. กิตตินนัท์ น้1อยมณี 10

หมายเหตุ : Stack เปรียบเสมือนกล่องใส่หนังสือใต้เตียง

Factorial

อ. กิตตินนัท์ น้1อยมณี 11

5!5!

ตรวจสอบดูว่า 5! หามีคําตอบหรอืยังFactorial

อ. กิตตินนัท์ น้1อยมณี 12

5!5!

ถ้ายังไม่มีคาํตอบ ก็เก็บใส่กล่อง

Push

Page 4: C Language - 09 ฟังก์ชันเรียกตัวเอง

04/01/57

Advance Computer Programming: อ.กิตตนินัท์ น้อยมณี 4

Factorial

อ. กิตตินนัท์ น้1อยมณี 13

4!4!

5!5!

ตรวจสอบดูว่า 4! หามีคําตอบหรอืยัง ถ้ายังก็เก็บใส่กล่อง

Push

Factorial

อ. กิตตินนัท์ น้1อยมณี 14

3!3!

5!5!

4!4!

ตรวจสอบดูว่า 3! หามีคําตอบหรอืยัง ถ้ายังก็เก็บใส่กล่อง

Push

Factorial

อ. กิตตินนัท์ น้1อยมณี 15

2!2!

5!5!

4!4!

3!3!

ตรวจสอบดูว่า 2! หามีคําตอบหรอืยงั ถ้ายังก็เก็บใส่กล่อง

Push

Factorial

อ. กิตตินนัท์ น้1อยมณี 16

1!1!

5!5!

4!4!

3!3!

2!2!

ตรวจสอบดูว่า 1! หามีคําตอบหรอืยัง ถ้ายังก็เก็บใส่กล่อง

Push

Page 5: C Language - 09 ฟังก์ชันเรียกตัวเอง

04/01/57

Advance Computer Programming: อ.กิตตนินัท์ น้อยมณี 5

Factorial

อ. กิตตินนัท์ น้1อยมณี 17

1!1!

5!5!

4!4!

3!3!

2!2!

แต่ 1! มีคําตอบแล้ว ดังนั้นจึงนับเปน็กรณีหยดุของ RecursionFactorial

อ. กิตตินนัท์ น้1อยมณี 18

5!5!

4!4!

3!3!

2!2!

Fac = 1Pop

Factorial

อ. กิตตินนัท์ น้1อยมณี 19

5!5!

4!4!

3!3!

Fac = 1 x 2Pop

Factorial

อ. กิตตินนัท์ น้1อยมณี 20

5!5!

4!4!

Fac = 1 x 2 x 3Pop

Page 6: C Language - 09 ฟังก์ชันเรียกตัวเอง

04/01/57

Advance Computer Programming: อ.กิตตนินัท์ น้อยมณี 6

Factorial

อ. กิตตินนัท์ น้1อยมณี 21

5!5!

Fac = 1 x 2 x 3 x 4Pop

Factorial

อ. กิตตินนัท์ น้1อยมณี 22

Fac = 1 x 2 x 3 x 4 x 5Pop

Factorial

อ. กิตตินนัท์ น้1อยมณี 23

Return Fac = 120Stack Empty

Factorial

• ดังนั้น Recursion จะดีกว่า Loop ตรงที่มันสามารถ

ทําซ้ําได้โดยการเรียกใช้ตัวมันเองให้ทํางานด้วย

ข้อมูลที่ต่างกันออกไป

• ทําไปเรื่อยๆ จนหมดก็จะได้คําตอบออกมาเอง

อ. กิตตินนัท์ น้1อยมณี 24

Page 7: C Language - 09 ฟังก์ชันเรียกตัวเอง

04/01/57

Advance Computer Programming: อ.กิตตนินัท์ น้อยมณี 7

Tower of Hanoi

อ. กิตตินนัท์ น้25อยมณี 25

Tower of Hanoi

อ. กิตตินนัท์ น้1อยมณี 26

Tower of Hanoi

อ. กิตตินนัท์ น้1อยมณี 27

เสาที่ 1 เสาที่ 2 เสาที่ 3(ต้นทาง)

จานที่ 3

จานที่ 2

จานที่ 1

(เสาพัก) (ปลายทาง)

Tower of Hanoi

อ. กิตตินนัท์ น้1อยมณี 28

เสาที่ 1 เสาที่ 2 เสาที่ 3(ต้นทาง)

จานที่ 3

จานที่ 2

จานที่ 1

(เสาพัก) (ปลายทาง)

เป้าหมายคอืยา้ยจานทุกจานมาอยู่ทีเ่สาปลายทางใหห้มด โดยเรียงตามขนาดของจานในลักษณะเดิม

Page 8: C Language - 09 ฟังก์ชันเรียกตัวเอง

04/01/57

Advance Computer Programming: อ.กิตตนินัท์ น้อยมณี 8

Tower of Hanoi

• โดยพื้นฐานแล้วจะมีเสาอยู่ทั้งหมด 3 ต้น

• และมีจานสวมเสาเหล่านี้อยู่

• ตามตํานานเล่าว่ามีจํานวนจานอยู่ทั้งหมด 64 จาน

• แต่ในโจทย์ปัญหานี้ลองแค่ 3 ก่อนก็พอ

อ. กิตตินนัท์ น้1อยมณี 29

Tower of Hanoi

ข้อกําหนดคือ

• เราจะย้ายจากเสาต้นทาง (เสาที่ 1) ไปยังเสา

ปลายทาง (เสาที่ 3)

• โดยมีเสาที่ 2 เป็นเสาพัก

• มีข้อห้ามคือ ห้ามมีจานใหญ่ทับจานเล็ก

อ. กิตตินนัท์ น้1อยมณี 30

Tower of Hanoi

ขั้นตอนการย้ายมี 3 ขั้นตอนดังนี้

1. ต้องย้ายจานข้างบนไปพักจนเหลือจานเดียว

แล้วค่อยย้ายจานล่างสุดไปไว้ที่ปลายทาง

อ. กิตตินนัท์ น้1อยมณี 31

Tower of Hanoi

อ. กิตตินนัท์ น้1อยมณี 32

เสาที่ 1 เสาที่ 2 เสาที่ 3(ต้นทาง)

จานที่ 3

จานที่ 2

จานที่ 1

(เสาพัก) (ปลายทาง)

Page 9: C Language - 09 ฟังก์ชันเรียกตัวเอง

04/01/57

Advance Computer Programming: อ.กิตตนินัท์ น้อยมณี 9

Tower of Hanoi

อ. กิตตินนัท์ น้1อยมณี 33

เสาที่ 1 เสาที่ 2 เสาที่ 3(ต้นทาง)

จานที่ 3

จานที่ 2

จานที่ 1

(เสาพัก) (ปลายทาง)

Tower of Hanoi

อ. กิตตินนัท์ น้1อยมณี 34

เสาที่ 1 เสาที่ 2 เสาที่ 3(ต้นทาง)

จานที่ 3

จานที่ 2

จานที่ 1

ตรวจดูว่าต้นทางเหลือจานเดียวรยึงั? (ถ้ายังไม่หมดใหท้ําจนกว่าจะหมด)

(เสาพัก) (ปลายทาง)

Tower of Hanoi

อ. กิตตินนัท์ น้1อยมณี 35

เสาที่ 1 เสาที่ 2 เสาที่ 3(ต้นทาง)

จานที่ 3

จานที่ 2

จานที่ 1

ย้ายมาเสาปลายทางไม่ได้ เพราะจาน2 ใหญ่กว่าจาน1

(เสาพัก) (ปลายทาง)

Tower of Hanoi

อ. กิตตินนัท์ น้1อยมณี 36

เสาที่ 1 เสาที่ 2 เสาที่ 3(ต้นทาง)

จานที่ 3

จานที่ 2

จานที่ 1

(เสาพัก) (ปลายทาง)

Page 10: C Language - 09 ฟังก์ชันเรียกตัวเอง

04/01/57

Advance Computer Programming: อ.กิตตนินัท์ น้อยมณี 10

Tower of Hanoi

อ. กิตตินนัท์ น้1อยมณี 37

เสาที่ 1 เสาที่ 2 เสาที่ 3(ต้นทาง)

จานที่ 3 จานที่ 2 จานที่ 1

จานที่ออกมาจากต้นทางต้องมาอยู่ทีป่ลายทั้งหมด ดังนั้นย้ายจาน 1 อีก

(เสาพัก) (ปลายทาง)

Tower of Hanoi

อ. กิตตินนัท์ น้1อยมณี 38

เสาที่ 1 เสาที่ 2 เสาที่ 3(ต้นทาง)

จานที่ 3 จานที่ 2

จานที่ 1

(เสาพัก) (ปลายทาง)

Tower of Hanoi

อ. กิตตินนัท์ น้1อยมณี 39

เสาที่ 1 เสาที่ 2 เสาที่ 3(ต้นทาง)

จานที่ 3 จานที่ 2

จานที่ 1

(เสาพัก) (ปลายทาง)

Tower of Hanoi

ขั้นตอนการย้ายมี 3 ขั้นตอนดังนี้

2. ย้ายจานใหญ่สุดไปไว้เสาปลายทางได้เลย

อ. กิตตินนัท์ น้1อยมณี 40

Page 11: C Language - 09 ฟังก์ชันเรียกตัวเอง

04/01/57

Advance Computer Programming: อ.กิตตนินัท์ น้อยมณี 11

Tower of Hanoi

อ. กิตตินนัท์ น้1อยมณี 41

เสาที่ 1 เสาที่ 2 เสาที่ 3(ต้นทาง)

จานที่ 3

จานที่ 2

จานที่ 1

(เสาพัก) (ปลายทาง)

Tower of Hanoi

อ. กิตตินนัท์ น้1อยมณี 42

เสาที่ 1 เสาที่ 2 เสาที่ 3(ต้นทาง)

จานที่ 3จานที่ 2

จานที่ 1

(เสาพัก) (ปลายทาง)

Tower of Hanoi

ขั้นตอนการย้ายมี 3 ขั้นตอนดังนี้

3. เป้าหมายครั้งนี้คือจะต้องย้ายจานจากเสาพัก

ทั้งหมดไปยังเสาปลายทางให้ได้ ซึ่งขั้นตอนคือ

(เป็นการเรียกงานย่อยๆ ออกมา หรือเป็น

Recursion นั่นเอง)

อ. กิตตินนัท์ น้1อยมณี 43

Tower of Hanoi

อ. กิตตินนัท์ น้1อยมณี 44

เสาที่ 1 เสาที่ 2 เสาที่ 3(ต้นทาง)

จานที่ 3จานที่ 2

จานที่ 1

(เสาพัก) (ปลายทาง)

Page 12: C Language - 09 ฟังก์ชันเรียกตัวเอง

04/01/57

Advance Computer Programming: อ.กิตตนินัท์ น้อยมณี 12

Tower of Hanoi

อ. กิตตินนัท์ น้1อยมณี 45

เสาที่ 1 เสาที่ 2 เสาที่ 3(ต้นทาง)

จานที่ 3

จานที่ 2

จานที่ 1

(เสาพัก) (ปลายทาง)

Tower of Hanoi

อ. กิตตินนัท์ น้1อยมณี 46

เสาที่ 1 เสาที่ 2 เสาที่ 3(ต้นทาง)

จานที่ 3

จานที่ 2

จานที่ 1

(เสาพัก) (ปลายทาง)

Tower of Hanoi

อ. กิตตินนัท์ น้1อยมณี 47

เสาที่ 1 เสาที่ 2 เสาที่ 3(ต้นทาง)

จานที่ 3

จานที่ 2

จานที่ 1

(เสาพัก) (ปลายทาง)

Tower of Hanoi

ถ้ามี 1 จาน ย้าย 1 ครัง้ (Hanoi 1 Dish: H(1) = 1)

ถ้ามี 2 จาน ย้าย 3 ครัง้ (Hanoi 2 Dish: H(2) = 2H(1) +1)

ถ้ามี 3 จาน ย้าย 7 ครัง้ (Hanoi 3 Dish: H(3) = 2H(2) +1)

ถ้ามี 4 จาน ย้าย 15 ครัง้ (Hanoi 4 Dish: H(4) = 2H(3) +1)

ถ้ามี 5 จาน ย้าย 31 ครัง้ (Hanoi 5 Dish: H(5) = 2H(4) +1)

อ. กิตตินนัท์ น้1อยมณี 48

เงื่อนไขการหยุด

สูตรในการเรียกตัวเองคือ

H(n) = 2H(n-1)+1

หมายเหตุ: เทคนิคคือพยายามหาความสัมพันธ์ของจานก่อนหน้ากับจานปัจจุบันให้ได้

Page 13: C Language - 09 ฟังก์ชันเรียกตัวเอง

04/01/57

Advance Computer Programming: อ.กิตตนินัท์ น้อยมณี 13

Tower of Hanoi

• พูดไปก็ไม่เห็นภาพ (ไม่เห็น Code)

• ดังนั้นลองมาดู Pseudo Code กัน

อ. กิตตินนัท์ น้1อยมณี 49

Tower of HanoiAlgorithm TowerHanoi( m:integer, i:integer, j:integer )

{ m = จํานวนจาน, i = เสาต้นทาง, j = เสาปลายทาง }

{ m >= 1, 1 <= i <= 3, 1 <= j <= 3 }

If m > 0 then

k := 6 – i – j

TowerHanoi( m – 1, i, k )

Print “Disc m from i to j”

TowerHanoi( m – 1, k, j )

End If

End Algorithmอ. กิตตินนัท์ น้1อยมณี 50

Tower of Hanoi

อ. กิตตินนัท์ น้1อยมณี 51

Tower of Hanoi

• m คือ จํานวนจาน

• i คือ เสาต้นทาง

• j คือ เสาปลายทาง

• k คือ เสาพัก หาได้จาก 6-i-j

อ. กิตตินนัท์ น้1อยมณี 52

หมายเหตุ: เลข 6 เกิดจากการเอาจาํนวนเสาทัง้หมดลบด้วยเสาต้นทางและเสาปลายทาง

Page 14: C Language - 09 ฟังก์ชันเรียกตัวเอง

04/01/57

Advance Computer Programming: อ.กิตตนินัท์ น้อยมณี 14

Tower of Hanoi

อ. กิตตินนัท์ น้1อยมณี 53

ย้ายจากเสาต้นทางไปยงัเสาพัก (ขั้นตอนที่ 1)

Tower of Hanoi

อ. กิตตินนัท์ น้1อยมณี 54

(ขั้นตอนที่ 2)

Tower of Hanoi

อ. กิตตินนัท์ น้1อยมณี 55

ย้ายเสาพักไปไว้ทีเ่สาปลายทาง (ขั้นตอนที่ 3)

Tower of Hanoi

ข้อสังเกต

Hanoi จะทํางานเมื่อ m เป็น 1 เป็นต้นไป (จึงจะเริ่ม

ทํางาน)

อ. กิตตินนัท์ น้1อยมณี 56

Page 15: C Language - 09 ฟังก์ชันเรียกตัวเอง

04/01/57

Advance Computer Programming: อ.กิตตนินัท์ น้อยมณี 15

Tower of Hanoi

• ยังมีอีกหลายโจทย์ที่ใช้ Recursion

• เป็นอีกหนึ่งทางเลือกที่น่าสนใจ

• มักใช้ในกรณีที่ไม่ต้องการเขียน Loop หรือเขียน

Loop ลําบาก ก็สามารถเอา Recursion มา

แก้ปัญหาได้

อ. กิตตินนัท์ น้1อยมณี 57

Tower of Hanoi

• ดังนั้นนับจากนี้ไป หากมีการวนรอบเกิดขึ้น เรา

ต้องมาคิดก่อนว่าจะใช ้Loop ดี หรือว่าใช้

Recursion ดี

อ. กิตตินนัท์ น้1อยมณี 58

Binary Search

อ. กิตตินนัท์ น้59อยมณี 59

Binary Search

เอาไว้ไปเจอกันในเรื่อง Divide-and-Conquer

อ. กิตตินนัท์ น้1อยมณี 60