9 רקורסיה

31
1 שיעור תשיעי: רקורסיהonline.shenkar.ac.il/moodle online.shenkar.ac.il/moodle http:// http:// קורס מבוא למדעי המחשב קורס מבוא למדעי המחשב סמסטר א סמסטר א' ' תשס תשס" ח כתובות ומצביעים כתובות ומצביעים: : תזכורת תזכורת לכל תא בזיכרון יש מספר סידורי לכל תא בזיכרון יש מספר סידורי) כתובת כתובת.( .( כל משתנה נשמר כל משתנה נשמר החל מכתובת החל מכתובת מסויימת מסויימת בזיכרון בזיכרון. . מצביע מצביע) פויינטר פויינטר( הוא משתנה ששומר כתובת של משתנה אחר הוא משתנה ששומר כתובת של משתנה אחר. . למשל למשלint int * * the_pointer_to_int the_pointer_to_int; . זהו מצביע ששומר כתובת זהו מצביע ששומר כתובת של משתנה מסוג של משתנה מסוגint int . הפעולה הפעולה& נותנת את כתובתו של משתנה נותנת את כתובתו של משתנה, , למשל למשל&i &i . . הפעולה הפעולה* ניגשת לערך שנמצא בכתובת ניגשת לערך שנמצא בכתובת מסויימת מסויימת. . למשל למשל* my_pointer_to_int my_pointer_to_int =10; =10; .

description

C LAN, C LANG

Transcript of 9 רקורסיה

Page 1: 9 רקורסיה

1

: שיע ור תשי עי

רקורסיה

online.shenkar.ac.il/moodleonline.shenkar.ac.il/moodlehttp://http://

קורס מבוא למדעי המחשבקורס מבוא למדעי המחשב

חח""תש סתש ס' ' סמסטר אסמסטר א

תזכורתתזכורת: : כתו בו ת ומצביעים כתו בו ת ומצביעים

כל משתנה נשמר כל משתנה נשמר ). ). כתובתכתובת((לכל תא בזיכרון יש מספר סידורי לכל תא בזיכרון יש מספר סידורי ••

. . בזיכרון בזיכרוןמסויימתמסויימתהחל מכתובת החל מכתובת

. . הוא משתנה ששומר כתובת של משתנה אחר הוא משתנה ששומר כתובת של משתנה אחר))פויינטרפויינטר((מצביע מצביע ••

intintלמשל למשל * * the_pointer_to_intthe_pointer_to_int;;.. זהו מצביע ששומר כתובת זהו מצביע ששומר כתובת

..intintשל משתנה מסוג של משתנה מסוג

**הפעולה הפעולה . . i&i&למשל למשל , , נותנת את כתובתו של משתנה נותנת את כתובתו של משתנה&&הפעולה הפעולה ••

למשל למשל . . מסויימתמסויימתניגשת לערך שנמצא בכתובת ניגשת לערך שנמצא בכתובת

**my_pointer_to_intmy_pointer_to_int=10;=10;..

Page 2: 9 רקורסיה

2

תזכורתתזכורת: : מציא ת הכתובת של משתנהמציא ת הכתובת של משתנה

intint main()main()

{{

intint i=10; i=10;

}}

התוכני ת התוכני ת הזיכרוןהזיכרון

75007500

טבל ת ה כ תובו ת טבל ת ה כ תובו ת

i i 75007500 44

משתנה משתנה כתובתכתובת גודלגודל1100

&i&i 75007500 זה זה

תזכורתתזכורת: : גישה לערך בכתו ב ת גישה לערך בכתו ב ת מסויי מתמסויי מת

intint main()main()

{{

char c=char c=‘‘AA’’; ;

}}

התוכני ת התוכני ת הזיכרוןהזיכרון

6565

92009200

טבל ת ה כ תובו ת טבל ת ה כ תובו ת

c c 92009200 11

משתנה משתנה כתובתכתובת

6565 זה זה (9200)*(9200)*

גודלגודל

Page 3: 9 רקורסיה

3

תזכורתתזכורת: : גישה למשתנה עלגישה למשתנה על--ידי מצביע ידי מצביע

::קטע תוכנית לדוגמאקטע תוכנית לדוגמא••

intint i=10;i=10;

intint **my_pointer_to_intmy_pointer_to_int;;

my_pointer_to_intmy_pointer_to_int == &&i;i;

**my_pointer_to_intmy_pointer_to_int=100;=100;

coutcout << "The value of i is now " << i;<< "The value of i is now " << i;

מצביע עליו שהפויינ טר במקום 100שמים

100יודפס המספר

int הגדרת מצביע על

i שמים במצביע את כת ובת המשתנה

100

i my_pointer_to_int

תזכורתתזכורת: : מצבי עים ופונקציותמצבי עים ופונקציות

מאפשרת לה לשנות אותו מאפשרת לה לשנות אותוהעברת כתובת של משתנה לפונקציההעברת כתובת של משתנה לפונקציה••

..אפילו שהוא לא מוגדר בהאפילו שהוא לא מוגדר בה

מה מה ((זו הסיבה שבהעברת מערך לפונקציה שונה ערכו המקורי זו הסיבה שבהעברת מערך לפונקציה שונה ערכו המקורי ••

).).שמועבר הוא כתובת ההתחלה של המערך בזיכרוןשמועבר הוא כתובת ההתחלה של המערך בזיכרון

Page 4: 9 רקורסיה

4

תזכורתתזכורת: : מצבי עים ופונקציות מצבי עים ופונקציות –– דוגמא דוגמא

, , intint של שני משתנים מסוג של שני משתנים מסוג כתובותכתובותתארנו פונקציה שמקבלת תארנו פונקציה שמקבלת ••

..בין הערכים שלהםבין הערכים שלהםומחליפה ומחליפה

void void swap(swap(intint **first, first, intint **second)second)

{{

intint temp;temp;

temp=temp=**first;first;

**first=first=**second;second;

**second=temp;second=temp;

}}

;swap(&i, &j);swap(&i, &j) ::ידיידי--השימוש למשל עלהשימוש למשל על

first ערך המשתנה שכת וב תו הועבר ה אל

יוחלף עם ערך המשתנ ה ש כתובת ו הועבר ה אל

second

פ ונקצ יה להחלפה בין ע רכי משתנ ים פ ונקצ יה להחלפה בין ע רכי משתנ ים : : דוגמאדוגמא

void void swap(intswap(int *first, *first, intint *second)*second)

{{

intint temp;temp;

temp=*first;temp=*first;

*first=*second;*first=*second;

*second=temp;*second=temp;

}}

intint main()main()

{ {

intint i=10, j=20;i=10, j=20;

swap(&i,&j);swap(&i,&j);

}}

Page 5: 9 רקורסיה

5

פ ונקצ יה להחלפה בין ע רכי משתנ ים פ ונקצ יה להחלפה בין ע רכי משתנ ים : : דוגמאדוגמא

void void swap(intswap(int *first, *first, intint *second)*second)

{{

intint temp;temp;

temp=*first;temp=*first;

*first=*second;*first=*second;

*second=temp;*second=temp;

}}

intint main()main()

{ {

intint i=10, j=20;i=10, j=20;

swap(&i,&j);swap(&i,&j);

}}

פ ונקצ יה להחלפה בין ע רכי משתנ ים פ ונקצ יה להחלפה בין ע רכי משתנ ים : : דוגמאדוגמא

void void swap(intswap(int *first, *first, intint *second)*second)

{{

intint temp;temp;

temp=*first;temp=*first;

*first=*second;*first=*second;

*second=temp;*second=temp;

}}

intint main()main()

{ {

intint i=10, j=20;i=10, j=20;

swap(&i,&j);swap(&i,&j);

}}

10

20i

j

Page 6: 9 רקורסיה

6

void void swap(intswap(int *first, *first, intint *second)*second)

{{

intint temp;temp;

temp=*first;temp=*first;

*first=*second;*first=*second;

*second=temp;*second=temp;

}}

intint main()main()

{ {

intint i=10, j=20;i=10, j=20;

swap(&i,&j);swap(&i,&j);

}}

10

first

20

second

i

j

פ ונקצ יה להחלפה בין ע רכי משתנ ים פ ונקצ יה להחלפה בין ע רכי משתנ ים : : דוגמאדוגמא

void void swap(intswap(int *first, *first, intint *second)*second)

{{

intint temp;temp;

temp=*first;temp=*first;

*first=*second;*first=*second;

*second=temp;*second=temp;

}}

intint main()main()

{ {

intint i=10, j=20;i=10, j=20;

swap(&i,&j);swap(&i,&j);

}}

10

first

temp

20

second

i

j

פ ונקצ יה להחלפה בין ע רכי משתנ ים פ ונקצ יה להחלפה בין ע רכי משתנ ים : : דוגמאדוגמא

Page 7: 9 רקורסיה

7

void void swap(intswap(int *first, *first, intint *second)*second)

{{

intint temp;temp;

temp=*first;temp=*first;

*first=*second;*first=*second;

*second=temp;*second=temp;

}}

intint main()main()

{ {

intint i=10, j=20;i=10, j=20;

swap(&i,&j);swap(&i,&j);

}}

10

first

temp 10

20

second

i

j

פ ונקצ יה להחלפה בין ע רכי משתנ ים פ ונקצ יה להחלפה בין ע רכי משתנ ים : : דוגמאדוגמא

void void swap(intswap(int *first, *first, intint *second)*second)

{{

intint temp;temp;

temp=*first;temp=*first;

*first=*second;*first=*second;

*second=temp;*second=temp;

}}

intint main()main()

{ {

intint i=10, j=20;i=10, j=20;

swap(&i,&j);swap(&i,&j);

}}

20

first

temp 10

20

second

i

j

פ ונקצ יה להחלפה בין ע רכי משתנ ים פ ונקצ יה להחלפה בין ע רכי משתנ ים : : דוגמאדוגמא

Page 8: 9 רקורסיה

8

void void swap(intswap(int *first, *first, intint *second)*second)

{{

intint temp;temp;

temp=*first;temp=*first;

*first=*second;*first=*second;

*second=temp;*second=temp;

}}

intint main()main()

{ {

intint i=10, j=20;i=10, j=20;

swap(&i,&j);swap(&i,&j);

}}

20

first

temp 10

10

second

i

j

פ ונקצ יה להחלפה בין ע רכי משתנ ים פ ונקצ יה להחלפה בין ע רכי משתנ ים : : דוגמאדוגמא

void void swap(intswap(int *first, *first, intint *second)*second)

{{

intint temp;temp;

temp=*first;temp=*first;

*first=*second;*first=*second;

*second=temp;*second=temp;

}}

intint main()main()

{ {

intint i=10, j=20;i=10, j=20;

swap(&i,&j);swap(&i,&j);

}}

20

10i

j

פ ונקצ יה להחלפה בין ע רכי משתנ ים פ ונקצ יה להחלפה בין ע רכי משתנ ים : : דוגמאדוגמא

Page 9: 9 רקורסיה

9

void void swap(intswap(int *first, *first, intint *second)*second)

{{

intint temp;temp;

temp=*first;temp=*first;

*first=*second;*first=*second;

*second=temp;*second=temp;

}}

intint main()main()

{ {

intint i=10, j=20;i=10, j=20;

swap(&i,&j);swap(&i,&j);

}}

20

10i

j

בלי מצביעים לא בלי מצביעים לא

יכולנו לשנות יו תר יכולנו לשנות יו תר

--ממש תנה אחד על ממש תנה אחד על

ידי פונקציהידי פונקציה

פ ונקצ יה להחלפה בין ע רכי משתנ ים פ ונקצ יה להחלפה בין ע רכי משתנ ים : : דוגמאדוגמא

תזכורתתזכורת: : מצבי עים ופונקציותמצבי עים ופונקציות

).).כלומר כתובת של משתנהכלומר כתובת של משתנה((פונקציה יכולה להחזיר מצביע פונקציה יכולה להחזיר מצביע ••

שהוגדר בתוך שהוגדר בתוך אבל לא כדאי להחזיר כתובת של משתנה אבל לא כדאי להחזיר כתובת של משתנה ••

כי אחרי שהפונקציה מסתיימת המשתנה כבר לא כי אחרי שהפונקציה מסתיימת המשתנה כבר לא , , הפונקציההפונקציה

).).גישה לשם תגרום לתעופהגישה לשם תגרום לתעופה((נמצא שם נמצא שם

Page 10: 9 רקורסיה

10

תזכורתתזכורת: : מצבי עים ומערכ ים מצבי עים ומערכ ים

ה מערך מכיל את ה מערך מכיל את --ומשתנהומשתנה, , תאי מערך נשמרים בזיכרון ברצףתאי מערך נשמרים בזיכרון ברצף••

). ). לא ניתן לשנות את ערכולא ניתן לשנות את ערכו ( (כתובת התא הראשון שלוכתובת התא הראשון שלו

. . י חישוב הכתובת שלהםי חישוב הכתובת שלהם""לכן אפשר לגשת לתאי מערך גם עלכן אפשר לגשת לתאי מערך גם ע••

..array[5]array[5] -- שקול ל שקול ל(array+5)*(array+5)*למשל למשל

כי כי , , המחשב יודע לאיזה כתובת לגשת כשעושים את החשבון הזההמחשב יודע לאיזה כתובת לגשת כשעושים את החשבון הזה••

..הוא יודע כמה מקום תופס כל תא במערך לפי סוג ערכיםהוא יודע כמה מקום תופס כל תא במערך לפי סוג ערכים

array[0] array[9]

.. . . . . . . ..500

array

) למשל (500כתובת

תזכורתתזכורת: : דוג מ א לגישה למע רך לפי כתו בתדוג מ א לגישה למע רך לפי כתו בת

intint i,array[10];i,array[10];

intint **ptrptr;;

): ): מדפיס ות את כל המערךמדפיס ות את כל המערך(( הלולא ות הבא ות עוש ות בדיוק א ותו דבר הלולא ות הבא ות עוש ות בדיוק א ותו דבר 33

for (i=0; i<10; i++)for (i=0; i<10; i++)

coutcout << << array[iarray[i];];

for (i=0; i<10; i++)for (i=0; i<10; i++)

coutcout <<<< *(*(array+iarray+i));;

forfor ((ptrptr=array; =array; ptrptr <= &array[9]; <= &array[9]; ptrptr++++))

coutcout <<<< **ptrptr;;

י קיד ום מצביע י קיד ום מצביע ""גישה עגישה ע

מכתובת התא הר אשו ן מכתובת התא הר אשו ן

עד כתובת התא ה אחרון עד כתובת התא ה אחרון

גישה רג ילה לת אי המערך גישה רג ילה לת אי המערך

הכת ובת הכת ובת גישה ל כל תא לפיגישה ל כל תא לפי

שלו יחס ית לתא הר אשו ן שלו יחס ית לתא הר אשו ן

Page 11: 9 רקורסיה

11

??שאלות נו ספות שאלות נו ספות

מצביעיםמצביעים

רקורסי ה

Page 12: 9 רקורסיה

12

רקערקע: : הגדרת נוסחאות הגדרת נוסחאות

דרך מקוב לת להגד י ר נוסחה או פעו לה מתמטי ת היא פשוט דרך מקוב לת להגד י ר נוסחה או פעו לה מתמטי ת היא פשוט , , כידועכידוע••

. . לרשום את שלב י החי שוב שלהלרשום את שלב י החי שוב שלה

))עם הרבה שלבי םעם הרבה שלבי ם((: : דוגמאות דוגמאות

n!=1*2*3*n!=1*2*3*…….*n.*n

aann= a*a*= a*a*……..*a..*a

פעמים פעמים n n

. . שלבשלב--אחראחר--מקובל גם לחשב את ערך הנו סחה שלב מקובל גם לחשב את ערך הנו סחה שלב ••

:: למשל למשל

4!=1*2*3*4=2*3*4=6*4=244!=1*2*3*4=2*3*4=6*4=24 ) ) כופל ים במספר הע וקב ב כל ש ל בכופל ים במספר הע וקב ב כל ש ל ב((

הגדרת נוסחאות הגדרת נוסחאות : : רקערקע

..יש דרך נוספת לה גדיר נ וס חאותיש דרך נוספת לה גדיר נ וס חאות••

אפשר להגד יר א ת הערך של אפשר להגד יר א ת הערך של , , במקום לרשום את כ ל שלבי החישובבמקום לרשום את כ ל שלבי החישוב••. . בעזרת ת וצאות השל בים שלפנ יובעזרת ת וצאות השל בים שלפנ יוהשלב האחר ון השלב האחר ון

: : ידיידי--במקום להגד יר עצרת עלבמקום להגד יר עצרת על, , למשללמשל••

n!=1*2*3*n!=1*2*3*…….*n.*n

::ידיידי-- אפשר להגדיר על אפשר להגדיר על

n!=n*n!=n*(n(n--1)!1)!

. . 1=!11=!1: : בצירוף ההגדרה ה התח לתית בצירוף ההגדרה ה התח לתית

: : ואז החישוב יהיהואז החישוב יהיה

4!=4*3!=4*3*2!=4*3*2*1!=4*3*2*1=4*3*2=4*6=244!=4*3!=4*3*2!=4*3*2*1!=4*3*2*1=4*3*2=4*6=24

Page 13: 9 רקורסיה

13

הגדרת נוסחאות הגדרת נוסחאות : : רקערקע

או או ,,""הגדרה רקורס יביתהגדרה רקורס יבית""הגדרה לפי תוצא ות הש לבי ם הקודמים נקרא ת הגדרה לפי תוצא ות הש לבי ם הקודמים נקרא ת ••. . של מה שרוצים לחשב של מה שרוצים לחשב""נוסחת רקורס יהנוסחת רקורס יה""

,,")")ב סיס הרק ורס יהב סיס הרק ורס יה("("צריך לציי ן את התוצא ה עבו ר ערך התחלתי כלש הו צריך לציי ן את התוצא ה עבו ר ערך התחלתי כלש הו ••..כי אחרת חישו ב הנ וסחה ב עצם לא מסתייםכי אחרת חישו ב הנ וסחה ב עצם לא מסתיים

::דוגמא נו ספתדוגמא נו ספת••

::י דיי די--אפשר להגדיר חזקה על אפשר להגדיר חזקה על , , aann=a*a*=a*a*……..*a..*a: : במקום במקום

aan n =a*a=a*ann--11, a, a00=1=1

16=1*16=1*4*4=16=1*16=1*4*4=400*4*4=4*4*4=411*4=4*4=4422: : ואז ואז

. . זאת הגדרה שקול ה זאת הגדרה שקול ה

כל דבר שמגדירים ומח שבי ם רקורסיב ית אפשר להגד י ר ולחשב גם לפי כל דבר שמגדירים ומח שבי ם רקורסיב ית אפשר להגד י ר ולחשב גם לפי ••").").אי טרטיביתאי טרטיביתהגדרה הגדרה ("("פירוט השלב ים פירוט השלב ים

? ? למה ז ה טו בלמה ז ה טו ב

..מהאיטרטיב יתמהאיטרטיב ית קצרה בהרב ה קצרה בהרב ה ההג דרה הרקורס יב ית ההג דרה הרקורס יב ית , , בהרבה מקריםבהרבה מקרים••

ההגדר ה הרקור סיב ית היא ה הגדר ה הטבעית ו הנ וחה ההגדר ה הרקור סיב ית היא ה הגדר ה הטבעית ו הנ וחה , , מסוי ימיםמסוי ימיםבמקרים במקרים ••

..ביותר של מה שר וצים לחש בביותר של מה שר וצים לחש ב

Page 14: 9 רקורסיה

14

? ? למה ז ה טו בלמה ז ה טו ב

כ סכ ום שני האיבר ים כ סכ ום שני האיבר ים כל איבר מוגדר כל איבר מוגדר יי' ' פיבו נאצפיבו נאצבסדרת בסדרת , , לדוגמאלדוגמא••::11כששנ י האי ברים ה ראשונ ים הם כששנ י האי ברים ה ראשונ ים הם , , שלפני ושלפני ו

1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89,1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89,……..

:: בסדרה הזאת ה י א בסדרה הזאת ה י אnn --ההגדרה הטב עית עב ור הא יבר ה ההגדרה הטב עית עב ור הא יבר ה ••

Fib(n)=Fib(nFib(n)=Fib(n--1)+Fib(n1)+Fib(n--2)2)

..Fib(1)=1, Fib(2)=1Fib(1)=1, Fib(2)=1 כאשר כאשר

כ לומר נו סחה כ לומר נו סחה ( (א יטרטיב יתא יטרטיב יתפחות נוח לרשום במקר ה הזה הגדרה פחות נוח לרשום במקר ה הזה הגדרה ••).).Fib(n)Fib(n)מפורשת של מפורשת של

..מהאיטרטיב יתמהאיטרטיב ית קצרה בהרב ה קצרה בהרב ה ההג דרה הרקורס יב ית ההג דרה הרקורס יב ית , , בהרבה מקריםבהרבה מקרים••

ההגדר ה הרקור סיב ית היא ה הגדר ה הטבעית ו הנ וחה ההגדר ה הרקור סיב ית היא ה הגדר ה הטבעית ו הנ וחה , , מסוי ימיםמסוי ימיםבמקרים במקרים ••

..ביותר של מה שר וצים לחש בביותר של מה שר וצים לחש ב

? ? למה ז ה טו בלמה ז ה טו ב

כ סכ ום שני האיבר ים כ סכ ום שני האיבר ים כל איבר מוגדר כל איבר מוגדר יי' ' פיבו נאצפיבו נאצבסדרת בסדרת , , לדוגמאלדוגמא••::11 כששנ י האי ברים ה ראשונ ים הם כששנ י האי ברים ה ראשונ ים הם ,,שלפני ושלפני ו

1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89,1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89,……..

:: בסדרה הזאת ה י א בסדרה הזאת ה י אnn --ההגדרה הטב עית עב ור הא יבר ה ההגדרה הטב עית עב ור הא יבר ה ••

Fib(n)=Fib(nFib(n)=Fib(n--1)+Fib(n1)+Fib(n--2)2)

..Fib(1)=1, Fib(2)=1Fib(1)=1, Fib(2)=1 כאשר כאשר

כ לומר נו סחה כ לומר נו סחה ( (א יטרטיב יתא יטרטיב יתפחות נוח לרשום במקר ה הזה הגדרה פחות נוח לרשום במקר ה הזה הגדרה ••).).Fib(n)Fib(n)מפורשת של מפורשת של

: : והחי שוב ה וא למשלוהחי שוב ה וא למשל••

Fib(4)=Fib(3)+Fib(2)=Fib(2)+Fib(1)+1=1+1+1=3Fib(4)=Fib(3)+Fib(2)=Fib(2)+Fib(1)+1=1+1+1=3

..מהאיטרטיב יתמהאיטרטיב ית קצרה בהרב ה קצרה בהרב ה ההג דרה הרקורס יב ית ההג דרה הרקורס יב ית , , בהרבה מקריםבהרבה מקרים••

ההגדר ה הרקור סיב ית היא ה הגדר ה הטבעית ו הנ וחה ההגדר ה הרקור סיב ית היא ה הגדר ה הטבעית ו הנ וחה , , מסוי ימיםמסוי ימיםבמקרים במקרים ••

..ביותר של מה שר וצים לחש בביותר של מה שר וצים לחש ב

Page 15: 9 רקורסיה

15

איך זה קשור לקורס שלנואיך זה קשור לקורס שלנו? ?

).).שלבשלב--אחרי אחרי --ש לב ש לב ( (איטרט יביאיטרט יבי בא ופןבא ופןעד עכשיו תמ יד ביצענ ו חי שובים עד עכשיו תמ יד ביצענ ו חי שובים ••n!=1*2*..*nn!=1*2*..*nי י ""הגדרנ ו עצרת עהגדרנ ו עצרת ע, , למשללמשל

: : ידיידי--וחי שבנ ו על וחי שבנ ו על

intint factorial (factorial (intint n)n)

{ {

intint result=1;result=1;

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

result=result*i;result=result*i;

return result;return result;

}}

. . מאפשרת להגדיר ולבצע חיש ובים גם באופ ן רקורס יבי מאפשרת להגדיר ולבצע חיש ובים גם באופ ן רקורס יביCCשפת שפת ••

: : למשל לחשב עצרת לפי ה הגדרהלמשל לחשב עצרת לפי ה הגדרה••

n!=n*(nn!=n*(n--1)! , 1!=11)! , 1!=1

? ? איך זה ני ראה בפועלאיך זה ני ראה בפועלנחשב עצרת לפי ההגדר ה הרקורס יב ית נחשב עצרת לפי ההגדר ה הרקורס יב ית ••

n!=n*(nn!=n*(n--1)! , 1!=11)! , 1!=1

intint factorial (factorial (intint n)n)

{ {

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

return n * factorial(nreturn n * factorial(n--1);1);

}}

).).עם פרמטרים אחריםעם פרמטרים אחרים((פונקצ יה יכ ול ה לקרו א לעצמה פונקצ יה יכ ול ה לקרו א לעצמה , , כלומרכלומר••

Page 16: 9 רקורסיה

16

? ? איך זה ני ראה בפועלאיך זה ני ראה בפועלנחשב עצרת לפי ההגדר ה הרקורס יב ית נחשב עצרת לפי ההגדר ה הרקורס יב ית ••

n!=n*(nn!=n*(n--1)! , 1!=11)! , 1!=1

intint factorial (factorial (intint n)n)

{ {

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

elseelse return n * factorial(nreturn n * factorial(n--1);1);

}}

).).עם פרמטרים אחריםעם פרמטרים אחרים((פונקצ יה יכ ול ה לקרו א לעצמה פונקצ יה יכ ול ה לקרו א לעצמה , , כלומרכלומר••

כי כי , , elseelse --אין צורך באין צורך ב, , כזכורכזכור

returnreturn מסיים את הפונקציה מסיים את הפונקציה

איך זה ע ובדאיך זה ע ובד? ? : : 33נאמר שבתו כני ת הראש ית קוראים לפו נקצ יה עם הפרמטר נאמר שבתו כני ת הראש ית קוראים לפו נקצ יה עם הפרמטר ••

#include<#include<iostream.hiostream.h>>

intint factorial (factorial (intint n)n)

{ {

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

return n * factorial(nreturn n * factorial(n--1);1);

}}

intint main()main()

{{

coutcout << "3! = " << factorial(3);<< "3! = " << factorial(3);

return 0;return 0;

}}

Page 17: 9 רקורסיה

17

איך זה ע ובד איך זה ע ובד

, , factorial(2)factorial(2) --משם יש קריאה למשם יש קריאה ל, , factorial(3)factorial(3) --קראנו לקראנו ל••

..factorial(1)factorial(1) --ומשם יש קריאה לומשם יש קריאה ל

שמחזיר ערך שמחזיר ערך , , factorial(2)factorial(2) -- מוחזר ערך ל מוחזר ערך לfactorial(1)factorial(1) --ממ••

..שמוחזר לתוכנית הראשיתשמוחזר לתוכנית הראשית, , factorial(3)factorial(3) --לל

factorial(3)factorial(3)mainmain factorial(2)factorial(2) factorial(1)factorial(1)

112*12*13*23*2

??factorial(3)factorial(3) מה עוש ה מה עוש ה

intint factorial (factorial (intint n)n)

{ {

if (n==1) if (n==1)

return 1;return 1;

return n * factorial(nreturn n * factorial(n--1);1);

}}

33

nn

Page 18: 9 רקורסיה

18

??factorial(3)factorial(3) מה עוש ה מה עוש ה

33

nnintint factorial (factorial (intint n)n)

{ {

if (n==1) if (n==1)

return 1;return 1;

return n * factorial(nreturn n * factorial(n--1);1);

}}

התנאי לא התנאי לא

מת קייםמת קיים

??factorial(3)factorial(3) מה עוש ה מה עוש ה

33

nnintint factorial (factorial (intint n)n)

{ {

if (n==1) if (n==1)

return 1; return 1;

return n * factorial(nreturn n * factorial(n--1);1);

}}

עובר לח שב א ת עובר לח שב א ת

factorial(2)factorial(2)

משתנים שהוגדרו משתנים שהוגדרו

בפונקציה נשארים בפונקציה נשארים

עד שהיא עד שהיא , , בזיכרוןבזיכרון

מסתיימתמסתיימת

Page 19: 9 רקורסיה

19

factorial(2)factorial(2) חישוב חישוב

22

nnintint factorial (factorial (intint n)n)

{ {

if (n==1) if (n==1)

return 1;return 1;

return n * factorial(nreturn n * factorial(n--1);1);

}}

33

nnfactorial(3)factorial(3) מש תני מש תני

factorial(2)factorial(2) חישוב חישוב

22

nnintint factorial (factorial (intint n)n)

{ {

if (n==1) if (n==1)

return 1;return 1;

return n * factorial(nreturn n * factorial(n--1);1);

}}

33

nn

factorial(3)factorial(3) מש תני מש תני

התנאי לא התנאי לא

מת קייםמת קיים

Page 20: 9 רקורסיה

20

factorial(2)factorial(2) חישוב חישוב

22

nnintint factorial (factorial (intint n)n)

{ {

if (n==1) if (n==1)

return 1;return 1;

return n * factorial(nreturn n * factorial(n--1);1);

}}

33

nnfactorial(3)factorial(3) מש תני מש תני

עובר לחש ב את עובר לחש ב את

factorial(1)factorial(1)

factorial(1)factorial(1) חישוב חישוב

11

nnintint factorial (factorial (intint n)n)

{ {

if (n==1) if (n==1)

return 1;return 1;

return n * factorial(nreturn n * factorial(n--1);1);

}}

33

nnfactorial(3)factorial(3) מש תני מש תני

22

nnfactorial(2)factorial(2) מש תני מש תני

Page 21: 9 רקורסיה

21

factorial(1)factorial(1) חישוב חישוב

11

nnintint factorial (factorial (intint n)n)

{ {

if (n==1) if (n==1)

return 1;return 1;

return n * factorial(nreturn n * factorial(n--1);1);

}}

33

nnfactorial(3)factorial(3) מש תני מש תני

22

nnfactorial(2)factorial(2) מש תני מש תני

factorial(1)factorial(1) חישוב חישוב

11

nnintint factorial (factorial (intint n)n)

{ {

if (n==1) if (n==1)

return 1;return 1;

return n * factorial(nreturn n * factorial(n--1);1);

}}

33

nnfactorial(3)factorial(3) מש תני מש תני

22

nnfactorial(2)factorial(2) מש תני מש תני

אל אל 11מחזיר מחזיר

factorial(factorial(22))

Page 22: 9 רקורסיה

22

factorial(2)factorial(2) חישוב חישוב

22

nnintint factorial (factorial (intint n)n)

{ {

if (n==1) if (n==1)

return 1;return 1;

return n * factorial(nreturn n * factorial(n--1);1);

}}

33

nnfactorial(3)factorial(3) מש תני מש תני

11הוחזר הוחזר

22מוחזר מוחזר

factorial(3)factorial(3) חישוב חישוב

33

nnintint factorial (factorial (intint n)n)

{ {

if (n==1) if (n==1)

return 1;return 1;

return n * factorial(nreturn n * factorial(n--1);1);

}} 22הוחזר הוחזר

בכך הס תיים החישו בבכך הס תיים החישו ב

66מוחזר מוחזר

Page 23: 9 רקורסיה

23

לבלב--נקודות לתשומ תנקודות לתשומ ת

):):הרקורסיההרקורסיה--בסיסבסיס((בלי השורה הזאת בלי השורה הזאת ••

if (n==1) if (n==1)

return 1;return 1;

..פעםפעם--החישוב לא היה מסתיים אףהחישוב לא היה מסתיים אף

factorialfactorial

בלי זה היינו ממשיכי ם לקרוא בלי זה היינו ממשיכי ם לקרוא

כל פעם כל פעם , , לפונקציה עד אינסוף לפונקציה עד אינסוף

עם פרמטר יותר ק ט ןעם פרמטר יותר ק ט ן

intint factorial (factorial (intint n)n)

{ {

if (n==1) if (n==1)

return 1;return 1;

return n * factorial(nreturn n * factorial(n--1);1);

}}

כלומר כלומר , , בכל פונקציה רקורסיבית חייב להיות תנאי עצירהבכל פונקציה רקורסיבית חייב להיות תנאי עצירה

..מקרה שבו הפונקציה תחזיר ערך בלי לקרוא לעצמה שובמקרה שבו הפונקציה תחזיר ערך בלי לקרוא לעצמה שוב

Page 24: 9 רקורסיה

24

עצירהעצירה: : לבלב--נקודות לתשומ תנקודות לתשומ ת

צריך גם לדאוג לכך שבאיזשהו שלב צריך גם לדאוג לכך שבאיזשהו שלב , , כדי שהתוכנית תסתייםכדי שהתוכנית תסתיים••

כמו שצריך לדאוג לכך שתנאי סיום כמו שצריך לדאוג לכך שתנאי סיום ( (יתקייםיתקייםתנאי העצירה תנאי העצירה

).).של לולאה יקרה מתישהושל לולאה יקרה מתישהו

עם אותו פרמטר שהועבר עם אותו פרמטר שהועבר למשל אם היינו קוראים לפונקציה למשל אם היינו קוראים לפונקציה ••

ולא ולא factorial(n)factorial(n)לדוגמא אם היינו כותבים לדוגמא אם היינו כותבים ( (אליהאליה

factorial(nfactorial(n--1)1)(( , ,אז לא היינו מתקדמים אל תנאי העצירהאז לא היינו מתקדמים אל תנאי העצירה , ,

..והפונקציה הייתה חוזרת על עצמה עד אינסוףוהפונקציה הייתה חוזרת על עצמה עד אינסוף

משתניםמשתנים: : לבלב--נקודות לתשומ תנקודות לתשומ ת

משתנים שהוגדרו בפונקציה משתנים שהוגדרו בפונקציה , , כשקוראים לפונקציה מתוך עצמהכשקוראים לפונקציה מתוך עצמה••..הקוראת נשארים בזיכרוןהקוראת נשארים בזיכרון

..עד שהפונקציה מסתיימתעד שהפונקציה מסתיימתכי המשתנים נשארים בזיכרון כי המשתנים נשארים בזיכרון ••

את את למלאלמלאזה עלול זה עלול , , אם נעשה הרבה מאוד קריאות רקורסיביותאם נעשה הרבה מאוד קריאות רקורסיביות••).).ניראה לזה דוגמא בהמשךניראה לזה דוגמא בהמשך((הזיכרון של המחשב הזיכרון של המחשב

נציי ן שעבור כ ל קריא ה לפונ קציה נ ידרש מקום בזי כרו ן גם עבור נציי ן שעבור כ ל קריא ה לפונ קציה נ ידרש מקום בזי כרו ן גם עבור ••, , הנק ודה שאל יה ה יא צרי כה לחזור ועבור הער ך שהי א צריכה ל החזירהנק ודה שאל יה ה יא צרי כה לחזור ועבור הער ך שהי א צריכה ל החזיר

.. מקום רב גם אם נחסוך במשתנ ים מקום רב גם אם נחסוך במשתנ יםשידרששידרשכך כך

Page 25: 9 רקורסיה

25

בהי רות בהי רות : : לבלב--נקודות לתשומ תנקודות לתשומ ת

מסויימיםמסויימיםאמרנו שלשימוש ברקורסיה יש יתרון במקרים אמרנו שלשימוש ברקורסיה יש יתרון במקרים ••

..שבהם קל יותר לכתוב באמצעותו את החישובשבהם קל יותר לכתוב באמצעותו את החישוב

, , לא תמיד קל למצוא הגדרה רקורסיבית לפונקציהלא תמיד קל למצוא הגדרה רקורסיבית לפונקציה, , מצד שנימצד שני••

..ולא תמיד קל להבין תוכניות שנכתבו באופן רקורסיביולא תמיד קל להבין תוכניות שנכתבו באופן רקורסיבי

..לכן נבחר להשתמש ברקורסיה במקרים שבאמת נוחים לכךלכן נבחר להשתמש ברקורסיה במקרים שבאמת נוחים לכך••

יעילות יעילות : : לבלב--נקודות לתשומ תנקודות לתשומ ת

מספר הקריאות לפונקציה היה זהה למספר מספר הקריאות לפונקציה היה זהה למספר , , במקרה שראינובמקרה שראינו••

..ידי לולאהידי לולאה--השלבים שהיינו עושים בחישוב עלהשלבים שהיינו עושים בחישוב על

ואז ואז , , אבל יתכנו מקרים שבהם נזדקק לקריאות רבות בהרבהאבל יתכנו מקרים שבהם נזדקק לקריאות רבות בהרבה••

..זמן הריצה עלול להיות הרבה יותר איטיזמן הריצה עלול להיות הרבה יותר איטי

..ניתן בהמשך דוגמא שממחישה את זהניתן בהמשך דוגמא שממחישה את זה••

Page 26: 9 רקורסיה

26

איך נחשב חז קה באופ ן רקו רסיב יאיך נחשב חז קה באופ ן רקו רסיב י? ?

): ): שלי לישלי לי--למעריך שלם וא י למעריך שלם וא י ((ההגדרה הרקורסיבית ההגדרה הרקורסיבית ••

aan n = a = a .. aann--11, , aa00=1=1

::CC --והפונקציה בוהפונקציה ב••

double power(double base, double power(double base, intint exp)exp)

{ {

if (exp==0) return 1;if (exp==0) return 1;

return base * power(base, expreturn base * power(base, exp--1);1);

}}

אפשר לטפל גם במעריך שליליאפשר לטפל גם במעריך שלילי

איך נחשב חז קה באופ ן רקו רסיב י איך נחשב חז קה באופ ן רקו רסיב י

::ההגדרה היאההגדרה היא, , אם יתכן מעריך שליליאם יתכן מעריך שלילי••

nn : :aa--n n = 1/a= 1/ann>>00עבור עבור

.. nn≥≥00 : :aan n = a = aעבור עבור aann--11, a, a00=1=1

::CC --והפונקציה בוהפונקציה ב••

double power(double base, double power(double base, intint exp)exp)

{ {

if (exp < 0) return 1/power(base, if (exp < 0) return 1/power(base, --exp);exp);

if (exp==0) return 1;if (exp==0) return 1;

return base * power(base, expreturn base * power(base, exp--1);1);

}}

Page 27: 9 רקורסיה

27

סדרת סדרת פיב ונאצפיב ונאצ''יי::נתנו את ה סדרה הזאת בת ור דוגמא לנ וסחה שמ וגדר ת באופן רקורס יב ינתנו את ה סדרה הזאת בת ור דוגמא לנ וסחה שמ וגדר ת באופן רקורס יב י••

fib(n)=fib(nfib(n)=fib(n--1)+fib(n1)+fib(n--2), fib(1)=1, fib(2)=12), fib(1)=1, fib(2)=1

::CC --נוכ ל לכתו ב את זה כך בנוכ ל לכתו ב את זה כך ב••

intint fib (fib (intint n)n)

{ {

if ((n==1) || (n==2)) if ((n==1) || (n==2))

return 1;return 1;

return fib(nreturn fib(n--1)+fib(n1)+fib(n--2);2);

}}

מה ההבדל בין הדוג מא הזאת ל ש תי מה ההבדל בין הדוג מא הזאת ל ש תי

??הדוגמאות הקודמו ת שראינוהדוגמאות הקודמו ת שראינו

י י ''פיבונאצפיבונאצחישוב ס דרת חישוב ס דרת נוספ ות נוספ ות שתי קריא ותשתי קריא ותיוצר ת יוצר ת , , n>2n>2נשים לב שכ ל קריא ה לפונ קציה הזאת עם נשים לב שכ ל קריא ה לפונ קציה הזאת עם ••

אז גם כל אחת מהן יוצרת שתי קריאו ת אז גם כל אחת מהן יוצרת שתי קריאו ת , , n>2n>2אם גם בהן אם גם בהן . . לפונקצ יהלפונקצ יה. . וכ ן הל אהוכ ן הל אה, , נוספותנוספות

נקבל מספר עצום של קריאות נקבל מספר עצום של קריאות , , 5050למשל למשל , , קטן יחסית קטן יחסיתnnכבר עבור כבר עבור , , כלומר כלומר). ). של כל הקריאו ת לפונקצ יה של כל הקריאו ת לפונקצ יהnn--ה ה ( ( שימלא ו את הזי כרון במשת נים שימלא ו את הזי כרון במשת נים , , לפונקצ יהלפונקצ יה

intint fib (fib (intint n)n)

{ {

if ((n==1) || (n==2)) if ((n==1) || (n==2))

return 1;return 1;

return fib(nreturn fib(n--1)+fib(n1)+fib(n--2);2);

}}

Page 28: 9 רקורסיה

28

fibfib קריאות לפו נקציה קריאות לפו נקציה

15004915004946368463682424

927359273528657286572323

332233

111122

111111

nnערךערךמספר קריאותמספר קריאות

יעילות יעילות -- יי''פיב ונאצפיב ונאצסדרת סדרת

..גם מבחינת היע ילו ת תהי ה בעיה רצי נית בפו נקצי ה הר קורס יבית שת יארנ וגם מבחינת היע ילו ת תהי ה בעיה רצי נית בפו נקצי ה הר קורס יבית שת יארנ ו••

הערכים הערכים 2222צריך לחשב לכ ל היו תר את צריך לחשב לכ ל היו תר את בסדרה בסדרה 2323--לחישו ב האי בר ה לחישו ב האי בר ה ••, , אבל בחיש וב הרקו רסיבי יתבצע ו עשרות א לפי קריא ות לפונקצ יהאבל בחיש וב הרקו רסיבי יתבצע ו עשרות א לפי קריא ות לפונקצ יה, , שלפני ושלפני ו

..עשרות אלפי ערכיםעשרות אלפי ערכיםכלומר יח ושב ו כלומר יח ושב ו

, , הסיב ה הי א ששנ י הערכ ים שמחושבים בקר יא ה הרקור סיבית ל א נשמריםהסיב ה הי א ששנ י הערכ ים שמחושבים בקר יא ה הרקור סיבית ל א נשמרים••. . ''וכווכו, , fib(1), fib(2)fib(1), fib(2)ולכ ן ברקור סיה י בוצע ו הרב ה פעמים את הקריא ות ולכ ן ברקור סיה י בוצע ו הרב ה פעמים את הקריא ות

אז אז , , אם פונקצי ה רקור סיבית צר יכה לק רוא לעצמ ה יותר מפעם אחתאם פונקצי ה רקור סיבית צר יכה לק רוא לעצמ ה יותר מפעם אחת: : מסקנהמסקנה••עבור מספרים גדול ים עבור מספרים גדול ים . . ויתאפ שר רק למספרים קטניםויתאפ שר רק למספרים קטנים, , חישוב ה הוא בע יית יחישוב ה הוא בע יית י

. . איט רטיביתאיט רטיביתנצטרך לחשב ולה גדיר נצטרך לחשב ולה גדיר

Page 29: 9 רקורסיה

29

איטר טיב י איטר טיב י -- יי''פיב ונאצפיב ונאצסדרת סדרת intint fib (fib (intint n)n)

{ {

intint i, temp, current=1, i, temp, current=1, prevprev=1;=1;

if ((n==1) || (n==2)) if ((n==1) || (n==2))

return 1;return 1;

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

{{

temp=current;temp=current;

current=current=current+prevcurrent+prev;;

prevprev=temp;=temp;

}}

return current;return current;

}}

רקורסי ה רקורסי ה –– שימושים נוספים שימושים נוספים . . רקורס יה יכ ול ה לשמש אות נו לא רק לחי שוב נ וסחא ותרקורס יה יכ ול ה לשמש אות נו לא רק לחי שוב נ וסחא ות••

י די פתרון של י די פתרון של --כל בעי ה שנית ן לפתור על כל בעי ה שנית ן לפתור על אפשר להשתמש בה עב ור אפשר להשתמש בה עב ור ••..פשוט ש לה פשוט ש לה //מקרה יותר קטןמקרה יותר קטן

אפשר לחשב ס כום איברי מערך לפי סכ ום האי ברים בלי הא יבר אפשר לחשב ס כום איברי מערך לפי סכ ום האי ברים בלי הא יבר לדוגמאלדוגמא••) ) עוצר ים כשנש אר איבר אחדעוצר ים כשנש אר איבר אחד: (: (ועוד הא יבר האחר וןועוד הא יבר האחר ון, , האחרו ןהאחרו ן

intint sum_array(intsum_array(int array[], array[], intint size)size)

{ {

if (size==1) return array[0];if (size==1) return array[0];

return array[sizereturn array[size--1] + sum_array(array,size1] + sum_array(array,size--1);1);

}}

Page 30: 9 רקורסיה

30

רקורסי ה רקורסי ה –– דוגמא נוספת דוגמא נוספת

אם אם 11ומחזירה ומחזירה , , הפונקציה הבאה בודקת אם תו נמצא במחרוזתהפונקציה הבאה בודקת אם תו נמצא במחרוזת••

: : 00כן ואחרת כן ואחרת

))עוצרים כשהגענו לסוף המחרוזת או כשמצאנו את התו המבוקשעוצרים כשהגענו לסוף המחרוזת או כשמצאנו את התו המבוקש ( (

intint in_str(charin_str(char **strstr, char letter), char letter)

{ {

if (*if (*strstr == == ‘‘\\00’’) return 0;) return 0;

if (*if (*strstr == letter) return 1;== letter) return 1;

return in_str(str+1, letter);return in_str(str+1, letter);

}}

רקורסי ה רקורסי ה -- סיכ ום סיכ ום כל ומר מוגדרת בעזרת כל ומר מוגדרת בעזרת ,,פונקצי ה רקורס יבית ה יא פו נקציה ש קוראת לעצמ הפונקצי ה רקורס יבית ה יא פו נקציה ש קוראת לעצמ ה••

בצירוף תנאי התחל ה עבור בצירוף תנאי התחל ה עבור , , פשוטיםפשוטים//הפעלתה עבור פרמטרים י ו תר קטניםהפעלתה עבור פרמטרים י ו תר קטנים..שמובטח שנגיע א לי ו במהלך החי שוב שמובטח שנגיע א לי ו במהלך החי שוב , , פרמטר כלשהופרמטר כלשהו

CC--קל לתרגם אותה לפונק ציה רקורס יב ית בקל לתרגם אותה לפונק ציה רקורס יב ית ב, , כשיש ל נו נ וסחה רק ורסי בי תכשיש ל נו נ וסחה רק ורסי בי ת••).).אבל לא תמיד ק ל למצוא נ יסוח רקו רסיב י אם הוא ל א נתון ל נו אבל לא תמיד ק ל למצוא נ יסוח רקו רסיב י אם הוא ל א נתון ל נו ((

אז כבר עבור אז כבר עבור , , אם בכל שלב הפו נקצי ה קו ראת לעצמה יותר מפעם אחתאם בכל שלב הפו נקצי ה קו ראת לעצמה יותר מפעם אחת••לכ ן חי שוב רקור סיב י הוא לכ ן חי שוב רקור סיב י הוא . . ערכים קטנים יד רשו הר בה זמן וזיכרו ן לחי שובערכים קטנים יד רשו הר בה זמן וזיכרו ן לחי שוב

..בעיית י במקרה כז הבעיית י במקרה כז ה

אז כתיבה אז כתיבה , , אם הפונקצי ה קוראת ל עצמה רק פעם אחת בכל שלבאם הפונקצי ה קוראת ל עצמה רק פעם אחת בכל שלב••רקורס יבית י כו לה לשמש כ דרך קצרה ואלג נטית לב יצו ע חישוב ים ופעול ות רקורס יבית י כו לה לשמש כ דרך קצרה ואלג נטית לב יצו ע חישוב ים ופעול ות

..בתירגו לבתירגו לדוגמא ות נו ספות י ו צגו דוגמא ות נו ספות י ו צגו . . נוספותנוספות

Page 31: 9 רקורסיה

31

??שאלות נו ספות שאלות נו ספות

שיעור תשי עי שיעור תשי עי––מבוא למדעי המחשב מבוא למדעי המחשב