I am currently trying to wrap my head around recursion so I picked a c++ textbook and began to read. The first couple of pages in the chapter on recursion were easy to understand but then I got to an item that doesn't make sense to me.
int height(node *p)
{
if(p==NULL)
return 0;
else{
return 1 + max(height(p->llink),height(p->rlink));
}
If max gives me the greatest of two values, how does max get its arguments from what height it's returning.
If anyone could help I would greatly appreciate it.....
To understand recursion you have to think recursively:
you can understand that an empty tree has height 0
you can understand that a generic non-empty tree has height 1 + the height of the longest subtree (which can be the one starting from the left or from the right)
Starting from this you can trivially understand the code. If you draw the tree you will see what happens. If you have for example
A
/ \
B C
/ \
D E
height(A) will return 1 + max(height(B), height(C))
height(B) will return 1 + max(height(D), height(E))
height(C) will return 1 + max(height(NULL), height(NULL)) = 1
height(D) will return 1 + max(height(NULL), height(NULL)) = 1
height(E) will return 1 + max(height(NULL), height(NULL)) = 1
so
height(A) = 1 + max(height(B), height(C)) =
= 1 + max(1 + max(height(D),height(E)), 1) =
= 1 + max(1 + 1, 1) = 1 + max(2, 1) = 3
(I omitted calls to height(NULL) because they are trivially 0 and otherwise it would have been too much verbose.)
The arguments to function are evaluated before function call.
So your example equivalent could look like the following (which maybe makes more sense?):
int height(node *p)
{
if(p==NULL)
return 0;
else{
int heightLeftSubtree = height(p->llink);
int heightRightSubtree = height(p->rlink);
return 1 + max(heightLeftSubtree, heightRightSubtree);
}
}
Related
int Fun(int m, int n)
{
if(n==0)
{
return n + 2;
}
return Fun(n-1, m-1) + Fun(m-1,n-1) + 1;
}
I'm completely lost as to what the 1st case would visually look like for this function. I don't understand why the function has two parameters and why we only return 1 parameter at the end with our base case. What would be the process to work this out? Any input you want to use to explain to me is fine I was trying (3,3). Although, now that I'm thinking about it how would this function look like if one of the inputs was smaller than the other like (3,2) or (2,3)?
Note that return n + 2; simplifies to return 2;.
The function takes two arguments (parameters) and returns a single value. That's like the operation of adding two numbers that you were taught in your first year at school.
Whether or not Fun(n - 1, m - 1) is called before Fun(m - 1, n - 1) is not specified by the C++ standard. So I can't tell you what the first recursive call will look like. This gives compilers more freedom in making optimisation choices. Of course the order in which the functions are called has no effect on the eventual result.
The best way of analysing what happens in your particular case is to use a line by line debugger.
There is nothing special about recursive functions - they work exactly like non-recursive functions.
Fun(3,3) does this:
if(3==0)
{
return 3 + 2;
}
return Fun(2, 2) + Fun(2, 2) + 1;
It needs the value of Fun(2,2), which does this:
if(2==0)
{
return 2 + 2;
}
return Fun(1, 1) + Fun(1, 1) + 1;
And that needs Fun(1,1), which does
if(1==0)
{
return 1 + 2;
}
return Fun(0, 0) + Fun(0, 0) + 1;
and Fun(0,0) does
if(0==0)
{
return 0 + 2;
}
return Fun(-1, -1) + Fun(-1, -1) + 1;
which returns 2 since the condition is true.
So, Fun(1, 1) will do
return 2 + 2 + 1;
which is 5, and Fun(2,2) will do
return 5 + 5 + 1;
which is 11, and Fun(3,3) will do
return 11 + 11 + 1;
which is 23.
I'm sure you can work through other examples on your own.
I am writing methods for a binary search tree and am having trouble understanding the basics of recursion. I found a method that checks for the size of the binary search tree and I see how it it going through each element of the tree, but I don't understand how it is counting the size exactly. Can someone please explain this to me?
Here is the method:
unsigned long BST::sizeHelper(BSTNode* r){
if (r == NULL){
return 0;
} else {
return (sizeHelper(r->left) + sizeHelper(r->right) + 1); //+1 for the root
}
}
I see the return statement, but I don't see any indication of how it is counting the elements as it goes through them.
Upon each return, the method adds at least one to the total size.
For example, consider the following tree:
(I'm bad at drawing, so I stole one online)
Steps are as follow:
Start from A, return size(B) + size(C) + 1.
For B, return size(D) + 0 + 1. (0 because B has no right child, i.e. NULL)
For D, return 0 + 0 + 1. size(D) = 1.
Now going back, size(B) = 1 + 1 = 2.
For C, return size(E) + size(F) + 1.
Similar to D, size(E) = size(F) = 1.
Going back again, size(C) = 1 + 1 + 1 = 3.
Finally, size(A) = 2 + 3 + 1 = 6.
I'm currently studying for my data structures exam and ran across a problem I could use clarification on. I'm supposed to create a function InsertZero(int k, int i) that inserts k zeroes after element i, checking indices each time and throwing appropriate exceptions.
I've done this, but I'm stuck on how to return a LinearList& that the function definition is asking me to in the class. I've tried return *element, return &element, and a few others to no avail. Where am I going wrong?
Additionally, I'm supposed to give the time complexity of the function as a "function of list length and k". I analyzed the steps throughout the function (see comments) and came up with O(k)...this doesn't use the list length, and I'm a bit confused on how to do so.
Any help will be greatly appreciated. I'm looking for comprehension, not just answers.
template <class T>
LinearList<T>& LinearList<T>::InsertZero(int i, int k)
{
//Complexity statements are in the form of
// "Number of steps" * "Number of times executed" = total
if ( i<0 || i> (MaxSize-1) || k<0) // 3 * 1 = 3
cout<<"Bad input exception thrown"<<endl;// 1 * 1 = 1
else if (k > (MaxSize-i-1) ) // 1 * 1 = 1
cout<<"NoMem exception thrown"<<endl; // 1 * 1 =1
else
{
while (k!=0) // 1 * k = k
{
element[i+1]=0; // 1 * k = k
i++; // 1 * k = k
k--; // 1 * k = k
}
return &element; // 1 * 1 = 1
}
//Total = 3+1+1+1+k+k+k+k+1 = 4k+7 = O(k)
}
I guess element array is a data member of the LinearList class. element is the basic C++ type (array of ints) whereas LinearList is derived one. I would do return *this at the end of your method.
The return type looks to be a the same type as the class. So you should return *this. It appears that elment should be a member variable, and that there is no need to return it.
For the code below, could anyone please tell me why the function always returns "0" if the return value for the base case (n==0) is 0? I know in order to correct this function, I'd simply have to replace "return 0" with "return 1", however, I'm trying to understand why does it return 0 for the base case below.
Thanks for your help
int factorial(int n) {
if (n == 0) {
return 0;
} else {
return n * factorial(n-1);
}
}
Edit: Hopefully, the code below has no logical errors ...
#include<iostream>
#include<math.h>
using namespace std;
long double factorial (long double n) {
if (n==0) return 1;
if (n<0) return -fabs((n*factorial(n+1)));
return n*(factorial(n-1));
}
int main () {
long double n;
cout << "Enter a number: ";
cin >> n;
cout << "Factorial of " << n << " is " << factorial(n) <<endl;
return 0;
}
If you take a look at how the factorial is defined you'll find something like:
f(0) = 1
f(1) = 1
f(n) = f(n-1) * n
So your function does indeed return the wrong value for factorial(0). The recursion in this function basically works by decrementing n in every new function call of factorial.
Let's assume you call factorial(3). n would that with 3, the else branch will get executed as n does not equal zero. We follow the third rule of our definition an call factorial(2) (which is n-1) and multiply the result of it by n. Your function will step down until factorial(0) is called and returns 0 which then is a factor of all previous calculations, resulting in 3*2*1*0, and that equals to 0.
This code is simply wrong. No matter which n > 0 it gets as argument, every value is eventually multiplied with 0 and therefore factorial( n ) = 0 for all n > 0.
It returns zero since any number times zero is zero. You start with some number n, say n=5. As you go through the recursion you have:
n * factorial(n-1)
5 * factorial(5-1)
5 * 4 * factorial(4-1)
5 * 4 * 3 * factorial(3-1)
5 * 4 * 3 * 2 * factorial(2-1)
5 * 4 * 3 * 2 * 1 * factorial(1-1)
But factorial(1-1) is factorial(0) which returns 0, so you get :
5 * 4 * 3 * 2 * 1 * 0 = 0
For the code below, could anyone please tell me why the function returns "0" if the return value for the base case (n==0) is 0?
Someone chose to do that. You'd have to ask the author why they did that.
I know in order to correct this function, I'd simply have to replace "return 0" with "return 1", however, I'm trying to understand why does it return 0 for the base case below.
Likely because the person who wrote it thought 0! was equal to 0.
I don't get you question entirely but lets cal the function f(int n): int okey to make it shorter
for n = 0 it will return 0 becaulse thats what you told it to do right: if(n == 0) return 0;
for n + 1 youll get the folowing pattern:
f(n+1) ==> n * f(n) becaulse thats wat you told it to do otherwise right? and f again will evaluate.
so thats why youre function will return 0 in any case and if you alter the base case to 1 youll get:
For whatever n (bigger than or equal to 0), you multiply a lot of numbers down to factorial(0) which returns 0.
The result of
n*(n-1)*(n-2)*...*3*2*1*0
is a big fat 0
P.S. Besides not computing properly, the code has a major flaw. If you give it a negative number, you make it cry.
I was calculating the Fibonacci sequence, and stumbled across this code, which I saw a lot:
int Fibonacci (int x)
{
if (x<=1) {
return 1;
}
return Fibonacci (x-1)+Fibonacci (x-2);
}
What I don't understand is how it works, especially the return part at the end: Does it call the Fibonacci function again? Could someone step me through this function?
Yes, the function calls itself. For example,
Fibonacci(4)
= Fibonacci(3) + Fibonacci(2)
= (Fibonacci(2) + Fibonacci(1)) + (Fibonacci(1) + Fibonacci(0))
= ((Fibonacci(1) + Fibonacci(0)) + 1) + (1 + 1)
= ((1 + 1) + 1) + 2
= (2 + 1) + 2
= 3 + 2
= 5
Note that the Fibonacci function is called 9 times here. In general, the naïve recursive fibonacci function has exponential running time, which is usually a Bad Thing.
This is a classical example of a recursive function, a function that calls itself.
If you read it carefully, you'll see that it will call itself, or, recurse, over and over again, until it reaches the so called base case, when x <= 1 at which point it will start to "back track" and sum up the computed values.
The following code clearly prints out the trace of the algorithm:
public class Test {
static String indent = "";
public static int fibonacci(int x) {
indent += " ";
System.out.println(indent + "invoked with " + x);
if (x <= 1) {
System.out.println(indent + "x = " + x + ", base case reached.");
indent = indent.substring(4);
return 1;
}
System.out.println(indent + "Recursing on " + (x-1) + " and " + (x-2));
int retVal = fibonacci(x-1) + fibonacci(x-2);
System.out.println(indent + "returning " + retVal);
indent = indent.substring(4);
return retVal;
}
public static void main(String... args) {
System.out.println("Fibonacci of 3: " + fibonacci(3));
}
}
The output is the following:
invoked with 3
Recursing on 2 and 1
invoked with 2
Recursing on 1 and 0
invoked with 1
x = 1, base case reached.
invoked with 0
x = 0, base case reached.
returning 2
invoked with 1
x = 1, base case reached.
returning 3
Fibonacci of 3: 3
A tree depiction of the trace would look something like
fib 4
fib 3 + fib 2
fib 2 + fib 1 fib 1 + fib 0
fib 1 + fib 0 1 1 1
1 1
The important parts to think about when writing recursive functions are:
1. Take care of the base case
What would have happened if we had forgotten if (x<=1) return 1; in the example above?
2. Make sure the recursive calls somehow decrease towards the base case
What would have happened if we accidentally modified the algorithm to return fibonacci(x)+fibonacci(x-1);
return Fibonacci (x-1)+Fibonacci (x-2);
This is terribly inefficient. I suggest the following linear alternative:
unsigned fibonacci(unsigned n, unsigned a, unsigned b, unsigned c)
{
return (n == 2) ? c : fibonacci(n - 1, b, c, b + c);
}
unsigned fibonacci(unsigned n)
{
return (n < 2) ? n : fibonacci(n, 0, 1, 1);
}
The fibonacci sequence can be expressed more succinctly in functional languages.
fibonacci = 0 : 1 : zipWith (+) fibonacci (tail fibonacci)
> take 12 fibonacci
[0,1,1,2,3,5,8,13,21,34,55,89]
This is classic function recursion. http://en.wikipedia.org/wiki/Recursive_function should get you started. Essentially if x less than or equal to 1 it returns 1. Otherwise it it decreases x running Fibonacci at each step.
As your question is marked C++, I feel compelled to point out that this function can also be achieved at compile-time as a template, should you have a compile-time variable to use it with.
template<int N> struct Fibonacci {
const static int value = Fibonacci<N - 1>::value + Fibonacci<N - 2>::value;
};
template<> struct Fibonacci<1> {
const static int value = 1;
}
template<> struct Fibonacci<0> {
const static int value = 1;
}
Been a while since I wrote such, so it could be a little out, but that should be it.
Yes, the Fibonacci function is called again, this is called recursion.
Just like you can call another function, you can call the same function again. Since function context is stacked, you can call the same function without disturbing the currently executed function.
Note that recursion is hard since you might call the same function again infinitely and fill the call stack. This errors is called a "Stack Overflow" (here it is !)
In C and most other languages, a function is allowed to call itself just like any other function. This is called recursion.
If it looks strange because it's different from the loop that you would write, you're right. This is not a very good application of recursion, because finding the n th Fibonacci number requires twice the time as finding the n-1th, leading to running time exponential in n.
Iterating over the Fibonacci sequence, remembering the previous Fibonacci number before moving on to the next improves the runtime to linear in n, the way it should be.
Recursion itself isn't terrible. In fact, the loop I just described (and any loop) can be implemented as a recursive function:
int Fibonacci (int x, int a = 1, int p = 0) {
if ( x == 0 ) return a;
return Fibonacci( x-1, a+p, a );
} // recursive, but with ideal computational properties
Or if you want to be more quick but use more memory use this.
int *fib,n;
void fibonaci(int n) //find firs n number fibonaci
{
fib= new int[n+1];
fib[1] = fib[2] = 1;
for(int i = 3;i<=n-2;i++)
fib[i] = fib[i-1] + fib[i-2];
}
and for n = 10 for exemple you will have :
fib[1] fib[2] fib[3] fib[4] fib[5] fib[6] fib[7] fib[8] fib[9] fib[10]
1 1 2 3 5 8 13 21 34 55``