Recursion in C++ - GitHub Pages · 2018. 9. 16. · Recursion in C++ CS 16: Solving Problems with...
Transcript of Recursion in C++ - GitHub Pages · 2018. 9. 16. · Recursion in C++ CS 16: Solving Problems with...
RecursioninC++
CS16:SolvingProblemswithComputersILecture#16
ZiadMatni
Dept.ofComputerScience,UCSB
LectureOutline
• LinkedLists:solutiontohomework#13
• RecursioninC++
5/31/18 Matni,CS16,Sp18 2
5/31/18 Matni,CS16,Sp18 3
#include<iostream>usingnamespacestd;structNode{
intdata;Node*link;
};TypedefNode*NodePtr;NodePtrsearch(NodePtrhead,inttarget);intmain(){
……someptr=search(head,6);…return0;}
NodePtrsearch(NodePtrhead,inttarget){
NodePtrhere=head;
if(here==NULL) returnNULL;else{
//gothruthelinkedlistandlookfortarget while((here->data!=target)&& (here->link!=NULL)) here=here->link;
//thewhileloopstoppedb/citeither//foundtargetoritfoundnothing
if(here->data==target) returnhere; else returnNULL;}
}
TranslatingsearchtoC++
OtherFunctionsWeMightCreateforLLs…
• Insertnodeatthehead• PrintoutallthevaluesintheLL• SearchtheLLforatarget
• InsertnodeattheendofLL• InsertnodeanywhereintheLL• Deleteanodeaccordingtosometargetvaluecriteria• SortanLLaccordingtosometargetvaluecriteriaetc…
5/31/18 Matni,CS16,Sp18 4
5/31/18 Matni,CS16,Sp18 5
5/31/18 Matni,CS16,Sp18 6
A child couldn't sleep, so her mother told a story about a little frog,
who couldn't sleep, so the frog's mother told a story about a little bear,
who couldn't sleep, so bear's mother told a story about a little weasel
...who fell asleep. ...and the little bear fell asleep; ...and the little frog fell asleep;
...and the child fell asleep.
RecursiveFunctions
• Recursive:(adj.)Repeatinguntoitself• Arecursivefunctioncontainsacalltoitself
• Whenbreakingataskintosubtasks, itmaybethatthesubtask isasmallerexample ofthesametask
5/31/18 Matni,CS16,Sp18 7
Example:TheFactorialFunction
Recall: x!=1*2*3…*xYoucouldcodethisoutaseither:• Aloop: (fork=1;k<x;k++){factorial*=k;}• Orarecursion/repetition:
factorial(x)=x*factorial(x-1) =x*(x-1)*factorial(x-2) =etc…untilyougettofactorial(1)(thenwhat?!?)
5/31/18 Matni,CS16,Sp18 8
Example:RecursiveFormulas• RecallfromMath,thatyoucancreatearecursiveformulafromasequenceExample:• Considerthearithmeticsequence:
5,10,15,20,25,30,…• InotethatIcanwriteeachnumberinthesequenceas:
an=an-1+5 (nbeingtheposition)
Forexample:a4=a3+5 =(a2+5)+5 =((a1+5)+5)+5 ßAtthispoint,Ineedtodesignatea1as5 =(5+5+5+5)=20
5/31/18 Matni,CS16,Sp18 9
TheBaseCase
• Ifweassumethatwestartthesequenceatn=1…(anarbitraryvalue) …thenwecoulddeviseanalgorithmfora(n)likethis:
1. Ifn=1,thenreturn5toa(n)2. Otherwise,returna(n-1)+5
• I’llneedtoknowwhatthatbasecaseis,otherwiseIrisknotendingmyrecursion(ornotmakingsenseofit)
5/31/18 Matni,CS16,Sp18 10
an=an-1+5
TheBASEcase
TheRECURSION(i.e.thefunctioncallingitself)
CaseStudy:VerticalNumbers
• ProblemDefinition:Writearecursivefunctionthattakesanintegernumberandprintsitoutonedigitatatimevertically:
voidwrite_vertical(intn);//Precondition:n>=0//Postcondition:niswrittentothescreenvertically// witheachdigitonaseparateline
5/31/18 Matni,CS16,Sp18 11
CaseStudy:VerticalNumbers
Analysis:• Takeadecimalnumber,like543.• HowdoIseparatethedigitsfromeachother?
– SothatIcanprintout5,then4,then3?
• Hint:Notethat543=500+40+3
5/31/18 Matni,CS16,Sp18 12
CaseStudy:VerticalNumbers
Algorithmdesign• Simplestcase (whatdowecallthatagain???)Ifnis1digitlong,justwritethenumber
• Moretypicalcase:1)Outputallbutthelastdigitvertically (recursion!)2)Writethelast(leastsignificant)digit (basecase!)– Step1isasmallerversionoftheoriginaltask-Therecursivecase– Step2isthesimplestcase-Thebasecase
5/31/18 Matni,CS16,Sp18 13
CaseStudy:VerticalNumbersThewrite_verticalalgorithm:
voidwrite_vertical(intn){
if(n<10)cout<<n<<endl;//n<10meansnisonlyonedigit
else//nistwoormoredigitslong{ write_vertical(n-with-the-least-significant-digit-removed); cout<<theleast-significantdigitofn<<endl;}
}
5/31/18 Matni,CS16,Sp18 14
CaseStudy:VerticalNumbers
• Notethat:n/10(integerdivision)returnsnwithjusttheleast-significantdigitremoved– So,forexample,85/10=8or124/10=12
• Whereas:n%10returnstheleast-significantdigitofn– Inthisexample,124%10=4
• Howmightwecombinetheseinthepreviousfunction?
5/31/18 Matni,CS16,Sp18 15
voidwrite_vertical(intn){
if(n<10)cout<<n<<endl; else {write_vertical
(n-without-last-digit);cout<<LSD<<endl; }}
CaseStudy:VerticalNumbers
Thewrite_verticalfunctioninC++ voidwrite_vertical(intn){
if(n<10)cout<<n<<endl; //n<10meansnisonlyonedigit
else//nistwoormoredigitslong{write_vertical(n/10);cout<<(n%10)<<endl;}}
5/31/18 Matni,CS16,Sp18 16
ExampleRun
5/31/18 Matni,CS16,Sp18 17
write_vertical(543)
write_vertical(54)
write_vertical(5)
cout<<5<<endl;
voidwrite_vertical(intn){
if(n<10)cout<<n<<endl; else {write_vertical(n/10);cout<<n%10<<endl; }}
cout<<4<<endl;
cout<<3<<endl;
stdout:543
①
②
③
④
⑤
“Infinite”Recursion• Afunctionthatneverreachesabasecase,intheory,willrunforever
– Why“intheory”?
• Whatifwewrotethefunctionwrite_vertical,withoutthebasecase voidwrite_vertical(intn)
{ write_vertical(n/10); cout<<n%10<<endl;
}• Willeventuallycallwrite_vertical(0),
whichwillcallwrite_vertical(0), whichwillcallwrite_vertical(0), whichwillcallwrite_vertical(0),
5/31/18 Matni,CS16,Sp18 18
whichwillcallwrite_vertical(0),whichwillcallwrite_vertical(0), whichwillcallwrite_vertical(0), whichwillcallwrite_vertical(0), whichwillcallwrite_vertical(0), whichwillcallwrite_vertical(0), …etc…
“Infinite”Recursion
• Inpractice,thecomputerwilloftenrunoutofresources(i.e.memoryusually)andtheprogramwillterminateabnormally– Thiscanhappeneveninnon-infiniterecursionsituations! (canyouthinkofacasewherethiscouldhappen?)
• So…rememberthatcomputersaremachines,notMathGodsanddesignyour(recursive)functionswiththatinmind!
5/31/18 Matni,CS16,Sp18 19
StacksforRecursion• Computersuseamemorystructurecalledastacktokeeptrackofrecursion• Stack:acomputermemorystructureanalogoustoastackofpaper
– Startatzero:nopapers,justknowledgeofwheretostart(viaa“stackpointer”)
– Toplacedataonthestack:writeitonapieceofpaperandplaceitontopofthestack– Toinsertmoreinformationonthestack:useanewsheetofpaper,writetheinformation,andplaceitonthetopofthestack
– Keepgoing…untilyoudon’t…
– Toretrieveinformation:youcanonlytakethetopsheetofpaper• Thenthrowitawaywhenityou’redone“reading”it
– Ifyouwantaccesstoanypaperfartherdown,gothruthestacktogettoit
5/31/18 Matni,CS16,Sp18 20
LIFO
• Thisschemeofhandlingsequentialdatainastackiscalled:LastIn-FirstOut(LIFO)
• WhenweputdatainaLIFO,wecallitapush• WhenwepulldataoutofaLIFO,wecallitapop
• TheothercommonschemeindataorganizationisFIFO(FirstIn-FirstOut)akaqueue
5/31/18 Matni,CS16,Sp18 21
Stacks&MakingtheRecursiveCall
Whenexecutionofafunctiondefinitionreachesarecursivecall…1. Executionispaused2. Dataisthensavedinanewplaceinthestackontop• Remember,thisispartofcomputermemory
3. Then,anewplaceinmemoryis“prepared”fortherecursivecalla) Anewfunctiondefinitioniswritten,argumentsarepluggedintoparametersb) Executionoftherecursivecallbegins
4. Newdataissavedontopofthestack5. Repeatuntilyougettothebasecase
5/31/18 Matni,CS16,Sp18 22
RF(4)
RF(3)
RF(2)
STACK
RF(1)BaseCase
Stacks&EndingRecursiveCalls
Whenarecursivefunctioncallgetstothebasecase…1. Thecomputerretrievesthetopmemoryunitofthestack2. Itresumescomputationbasedontheinformationonthesheet3. Whenthatcomputationends,thatmemoryunitis“discarded”4. Themem.unitonthestackisretrievedsothatprocessingcan
resume5. Theprocesscontinuesuntilthestackisbacktoitoriginalstatus
5/31/18 Matni,CS16,Sp18 23
RF(4)
RF(3)
RF(2)
STACK
RF(1)BaseCase
Stack Overflow
• Stacksarefinitethings…• Infiniterecursionscanforcethestack togrowbeyonditsphysicallimits
• Theresultofthiserroneousoperationiscalledastackoverflow– Thiscausesabnormalterminationoftheprogram
5/31/18 Matni,CS16,Sp18 24Imagefromstackoverflow.com
RecursiveFunctionsforValues
• Recursivefunctionsdon’thavetobevoidtypes– Theycanalsoreturnvalues
• Thetechniquetodesignarecursivefunctionthatreturnsavalueisbasicallythesameaswhatwedescribedearlier…
5/31/18 Matni,CS16,Sp18 25
ProgramExample:APowersFunctionExample:Defineanewpowerfunction(nottheonein<cmath>)• Letitreturnaninteger,23,whenwecallthefunctionas:inty=power(2,3);
• Usethefollowingdefinition:xn=xn-1*x i.e.23=22*2– Notethatthisonlyworksifnisapositivenumber
• TranslatingtherightsideofthatequationintoC++gives:power(x,n-1)*x– Whatisthebase/stoppingcase?
It’swhenn=0– Whatshouldhappenthen?
power()shouldreturn1
5/31/18 Matni,CS16,Sp18 26
Tracingpower(2,3)
1power(2,0)*2power(2,1)*2power(2,2)*2power(2,3)
5/31/18 Matni,CS16,Sp18 27
pushingintothestack
1 1*2
2*2
4*2
=8
poppingoutofthestack
5/31/18 Matni,CS16,Sp18 28
Stoppingcase
intpower(intx,intn){//Beforeyoudoabase-case,youshouldtakecareof//“illegal”operations…if(n<0){ cout<<“Cannotusenegativepowersinthisfunction!\n”; exit(1);}
if(n>0) return(power(x,n–1)*x);
else//i.e.ifn==0 return(1);
}
RecursionversusIteration
• Anytaskthatcanbeaccomplishedusingrecursioncanalsobedonewithoutrecursion(usingloops)
• Anon-recursiveversionofarepeatingfunctioniscalledaniterative-version
5/31/18 Matni,CS16,Sp18 29
RecursionversusIteration
• Arecursiveversionofafunction…– Usuallyrunsalittleslower,takesupmorememory– BUTitusescodethatiseasiertowriteandunderstand
5/31/18 Matni,CS16,Sp18 30
intpower(intx,intn){if(n==0)return(1);elsereturn(power(x,n-1)*x);}
intpower(intx,intn){intp=1;for(intk=1;k<=n;k++)p*=x;return(p);}
RecursiveVersion
IterativeVersion
YOURTO-DOs
q TurninLab9onMondayq DoHW14byTuesdayq New(ANDLAST)labnextweek:Lab10
q VisitProf’sandTAs‘officehoursifyouneedhelp!
5/31/18 Matni,CS16,Sp18 31
5/31/18 Matni,CS16,Sp18 32