400 likes | 571 Views
Thursday, January 25, 2007. " To define recursion, we must first define recursion. " - Anonymous. Remaining Lectures Schedule. Thursday January 25 (Today) Friday January 26 Thursday February 1 Friday February 2 Saturday February 3 Tuesday February 6. What is wrong here?
E N D
Thursday, January 25, 2007 "To define recursion, we must first define recursion." - Anonymous
Remaining Lectures Schedule • Thursday January 25 (Today) • Friday January 26 • Thursday February 1 • Friday February 2 • Saturday February 3 • Tuesday February 6
What is wrong here? int* function_returns_ptr(void){ int array[8]={1,2,3,4,5,6,7,8}; int *ptrArray=array; return (ptrArray+4); } int main(void){ int *result=function_returns_ptr(); cout<<*result<<endl; return 0; }
ReferencesSafer and simpler use of memory addresses are referencesWhen a reference parameter is used, the address of an argument is automatically passed to the function. Within the function the operations on reference parameter are automatically de-referenced.
Calling Functions • With call by reference, the caller gives the called function the ability to directly access the caller’s data and to modify that data if the called function so chooses. • To indicate that a function parameter is passed by reference, simply follow the parameter’s type in the function prototype by an ampersand &. • e.g. void myFunction( int &x);
Calling Functions int squareByValue(int a); void squareByReference(int &aref);
Calling Functions int main() { int x = 2, z = 4; cout << "x = " << x << " before squareByValue" ; squareByValue(x) ; cout<< "x = " << x << " after squareByValue" ; cout << "z = " << z << "before squareByReference”; squareByReference(z); cout << "z = " << z << " after squareByReference"; return 0; }
Calling Functions int squareByValue(int a) { return a *= a; //caller's argument not modified } void squareByReference(int &cRef) { cRef *= cRef; // caller's argument modified }
Calling Functions -II void swap(int &sa, int &sb){ int temp=sa; sa=sb; sb=temp; } int main() { int a=3; int b=5; cout<<a<<" "<<b<<endl; swap(a, b); cout<<a<<" "<<b<<endl; return 0; }
void f1(int *num) { cout<<*num<<endl; num++; num++; cout<<*num<<endl; } int main(void){ int a[8]={1,2,3,4,5,6,7,8}; int *aptr=a; f1(aptr); cout<<*aptr<<endl; return 0;} //OUTPUT? Calling Functions with pointers
1 3 1 Calling Functions with pointers
void f1(int* &num) { cout<<*num<<endl; num++; num++; cout<<*num<<endl; } int main(void){ int a[8]={1,2,3,4,5,6,7,8}; int *aptr=a; f1(aptr); cout<<*aptr<<endl; return 0;} //OUTPUT?
1 3 3
The most common use of references is in function parameters.
Reference variables int a=6; int &b =a; cout<<b<<" "<<a<<endl; b=3; cout<<b<<" "<<a<<endl; References must be initialized
Reference variables 6 6 3 3
Reference variables What is wrong here? int a=6; int &b=a+4; cout<<b<<" "<<a<<endl;
A function call ends when • Return statement is executed. • The closing } brace of the end of function is reached. • At the end of function call, flow of control returns back to the calling function.
void X() { int a = 1; int b = 2; // T1 Y(a); // T3 Y(b); // T5 } void Y(int p) { int q; q = p + 2; // T2 (first time through), T4 (second time through) }
Recursion A recursive function is one that calls itself. Recursive functions have two parts • Stopping Condition(s) -- solving the base case(s). • Recursive call -- breaking the problem down.
Recursion When a function calls itself, new local variables and parameters are allocated storage on stack and the function is executed with these new variables from the beginning of function.
void PrintFunc(int x) { int y=x-1; if (x<=0) return; cout<<"In Print Func before recursive call. x="<<x<<endl; PrintFunc(y); cout<<"In Print Func after recursive call. x="<<x<<endl; } int main(void) { PrintFunc(3); //... }
x is 3 void PrintFunc(int x) { int y=x-1; if (x<=0) return; cout<<"In Print Func before recursive call. x="<<x<<endl; PrintFunc(y); cout<<"In Print Func after recursive call. x="<<x<<endl;}
x is 3 void PrintFunc(int x) { int y=x-1; if (x<=0) return; cout<<"In Print Func before recursive call. x="<<x<<endl; PrintFunc(y); cout<<"In Print Func after recursive call. x="<<x<<endl;} void PrintFunc(int x) { int y=x-1; if (x<=0) return; cout<<"In Print Func before recursive call. x="<<x<<endl; PrintFunc(y); cout<<"In Print Func after recursive call. x="<<x<<endl;} x is 2
x is 3 void PrintFunc(int x) { int y=x-1; if (x<=0) return; cout<<"In Print Func before recursive call. x="<<x<<endl; PrintFunc(y); cout<<"In Print Func after recursive call. x="<<x<<endl;} void PrintFunc(int x) { int y=x-1; if (x<=0) return; cout<<"In Print Func before recursive call. x="<<x<<endl; PrintFunc(y); cout<<"In Print Func after recursive call. x="<<x<<endl;} void PrintFunc(int x) { int y=x-1; if (x<=0) return; cout<<"In Print Func before recursive call. x="<<x<<endl; PrintFunc(y); cout<<"In Print Func after recursive call. x="<<x<<endl;} x is 2 x is 1
x is 3 void PrintFunc(int x) { int y=x-1; if (x<=0) return; cout<<"In Print Func before recursive call. x="<<x<<endl; PrintFunc(y); cout<<"In Print Func after recursive call. x="<<x<<endl;} void PrintFunc(int x) { int y=x-1; if (x<=0) return; cout<<"In Print Func before recursive call. x="<<x<<endl; PrintFunc(y); cout<<"In Print Func after recursive call. x="<<x<<endl;} void PrintFunc(int x) { int y=x-1; if (x<=0) return; cout<<"In Print Func before recursive call. x="<<x<<endl; PrintFunc(y); cout<<"In Print Func after recursive call. x="<<x<<endl;} void PrintFunc(int x) { int y=x-1; if (x<=0) return; cout<<"In Print Func before recursive call. x="<<x<<endl; PrintFunc(y); cout<<"In Print Func after recursive call. x="<<x<<endl;} x is 2 x is 1 x is 0
x is 3 void PrintFunc(int x) { int y=x-1; if (x<=0) return; cout<<"In Print Func before recursive call. x="<<x<<endl; PrintFunc(y); cout<<"In Print Func after recursive call. x="<<x<<endl;} void PrintFunc(int x) { int y=x-1; if (x<=0) return; cout<<"In Print Func before recursive call. x="<<x<<endl; PrintFunc(y); cout<<"In Print Func after recursive call. x="<<x<<endl;} void PrintFunc(int x) { int y=x-1; if (x<=0) return; cout<<"In Print Func before recursive call. x="<<x<<endl; PrintFunc(y); cout<<"In Print Func after recursive call. x="<<x<<endl;} x is 2 x is 1
x is 3 void PrintFunc(int x) { int y=x-1; if (x<=0) return; cout<<"In Print Func before recursive call. x="<<x<<endl; PrintFunc(y); cout<<"In Print Func after recursive call. x="<<x<<endl;} void PrintFunc(int x) { int y=x-1; if (x<=0) return; cout<<"In Print Func before recursive call. x="<<x<<endl; PrintFunc(y); cout<<"In Print Func after recursive call. x="<<x<<endl;} x is 2
x is 3 void PrintFunc(int x) { int y=x-1; if (x<=0) return; cout<<"In Print Func before recursive call. x="<<x<<endl; PrintFunc(y); cout<<"In Print Func after recursive call. x="<<x<<endl;}
In Print Func before recursive call. x=3 In Print Func before recursive call. x=2 In Print Func before recursive call. x=1 In Print Func after recursive call. x=1 In Print Func after recursive call. x=2 In Print Func after recursive call. x=3
int RecFunc(int x){ int sum; if(x<=1) return 1; sum = x*x + RecFunc(x-1); cout<<sum<<endl; return sum; } int main(void){ int ans; ans=RecFunc(5); cout<<"ans="<<ans<<endl; //... }
5 14 30 55 ans=55
Recursion vs. Iteration Similarities: Both iteration and recursion involve repetition: • Iteration explicitly uses a repetition structure; • recursion achieves repetition through repeated function calls. Iteration and recursion each involve a termination test • iteration terminates when the loop condition fails • recursion terminates when a base case is recognized.
Recursion vs. Iteration Similarities: Both iteration and recursion can occur infinitely: • An infinite loop can occur with iteration, • Infinite recursion can occur when the base case is not reached.
SELF TEST: Recursion int factorial(int N){ int ans; if (N<=1) return 1; //base case ans=factorial(N-1)*N; return ans; } int main() { int answer=factorial(4); cout<<answer; return 0; } Stack contents
Example: Binary Search int BinarySearch(int no, int low,int high, int* iarray); int main(void) { int num, i, size=15; int* array=new int[size]; for (i=0; i<size; i++) array[i]=13*i+4; for (i=0; i<size; i++) cout<<array[i]<<" "; cout<<endl; cin>>num; if(BinarySearch(num, 0, size-1, array)) cout<<"found"<<endl; else cout<<"not found"<<endl; return 0; }
Example: Binary Search int BinarySearch(int no, int low,int high, int* iarray){ if (low>high){ return 0; } int mid=low+(high-low)/2; if (no==iarray[mid]) return 1; else if (no>iarray[mid]) return BinarySearch(no, mid+1, high, iarray); else return BinarySearch(no, low, mid-1, iarray); }