简体   繁体   中英

Difficulty understanding multiple recursive calls

function max(arr, first, last){
if (first==last) return arr[first];
mid=first+(last-first)/2;
a=max(arr, first,mid);
b=max(arr, mid+1,last);
if (a<b) return b;
return a;
}

I'm having trouble understanding this recursive function as I don't really understand how the flow works when assigning the variables. My understanding is that when a=max(arr, first,mid); a will keep calling the function until the base case occurs - so I am safe to assume while this is happening

b=max(arr, mid+1,last);     
if (a<b) return b;
    return a;`

is not executed until 'a' is done calling? And when the flow reaches 'b' and it starts recursivly calling, does it affect a=max(arr, first,mid); - in that it will apply different values to a?

My understanding in context to finding the max was that a would find the maximum element in the first half and b would find the maximum element in the second half but I don't understand how it can do that when if (a<b) return b; return a; if (a<b) return b; return a; isn't called until at the end when a and b have values, my thought was that it would check this so that it could find the maximum in a and maximum in b and then compare the max of both halves to find the maximum element in arr?

Sorry if the Q is vague I'm just trying to better my understanding of recursion

You're trying to understand how it works by following it step by step, chasing every single call all the way down. Don't do that, it's confusing.

Look at what one call does, without worrying about what happens in functions the current invocation of max() calls. Yes, it calls itself, and even does it twice. Both of those calls are function calls that return a value, and as far as the current invocation of max() is concerned, they might as well just be numbers.

If I replaced the lines assigning a and b with this:

a = 13;
b = 42;

then you wouldn't have any trouble understanding what it does. And if I replaced them with this:

a = max_implemented_with_a_for_loop(arr, first, mid);
b = max_implemented_with_a_for_loop(arr, mid+1, last);

then you wouldn't have trouble with that either. The recursive version isn't that different.

Recursive functions like this work by taking a big problem, dividing it into smaller subproblems, solving the subproblems, and combining the solutions to solve the big problem. It uses itself to solve the subproblems, and if we didn't have base cases, there would be a snag - there comes a point where you can't subdivide the problem any further, and you need another way of solving these tiny subproblems. But it isn't much of a snag, since a subproblem that's too small to divide anymore is easy to solve. The base case just notices that we've got something easy to solve directly and/or can't be divided any further, and handles it.

Each recursive call has a smaller non-negative value of last-first. So if the first call has non-negative value of last-first then each call, including the first, terminates.

If last==first then it returns the only element in the range as maximum.

Otherwise it returns the larger of the maximum of the first half (a) and the maximum of the second half (b).

In either case the maximum is correctly calculated, and there are no other cases.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM