 And welcome to Intro to Java with an emphasis on AP Computer Science A with Tokyo EdTech. That is me. Our topic today is recursion. Now the AP usually introduces this unit at the very end. I think it fits here better. We just completed static methods. And these are basically static methods. So I thought this would be a good place. Now don't spend too much time worrying about this particular topic. It's only two, maybe three percentage points of the final exam. I think as long as you really know how to trace these types of functions and to be able to work through an example, I think you'll be okay with the multiple choice questions. They don't really appear on the free response questions as far as I know. So let's go ahead and take a look at what we're going to learn. First, talk a little bit about what recursion is. I'll give you a little non-recursive example to get the idea going. Then the same thing in our recursive example. I'll talk something about called the maximum recursion depth and a base case, which is super-duper important in here. So by the end of this, you'll understand what all this is. Then we'll do one example of a recursion algorithm, the Fibonacci sequence. And then we'll talk a little bit about printing order and just kind of how things work, how to think about working through the code. So let's go ahead and take a look here. So let's start with a non-recursive example. So what am I talking about? Well, what is recursion? So a recursive algorithm or a recursive method is a method that calls itself. So in my mind, I think of it a lot like a loop, but in method form. So recursion is used for certain types of problems where the overall problem is a subsection of itself. And you'll see that with the Fibonacci sequence, what I mean with that. Let's take a look at a non-recursive example. So I'm going to go ahead and create some static methods here. So I'm going to make a method called public static void print1. It's a very exciting method. And this method, go for your system.out.println, and actually literally just print1. So I'm going to go ahead and copy that and paste it. We'll print1, print2, and we will print3. So it's going to kind of build up to recursion. So hopefully this will kind of make sense. Okay, so we've got three functions, print1, print2, and print3. So let's go ahead and do print1. We'll call them print2 and print3. Let's go ahead and compile it. We'll run it. Okay, very exciting. So we've got one, two, and three. So you can see here we call print1, returns back to the top. We call print2, returns back to the top. Call print3, returns back to the top. Very, very exciting. So how about this? What if we did this? Print1, and then inside print1, we call print2. Then inside print2, we call print3. So now our execution will go from here from line six. It would jump down to 21, 22, 23. We get to 24. We jump down to 27, 28, 29. We get to 30. We jump down to 33, 34, 35. Now this is interesting. So this is done. We come back to here. There's nothing after it. This is done. We come back to here. This is done. Then we go back to here. That's important for the last part of this as well. Okay. So here what we've done is we've used three separate methods, but each method is calling the next method. So what we want to do now is the same thing, but with one method. So let's go ahead and do this. So space there. So I'm going to make a new method called print num. And I'm going to go ahead and start with one. So I'm going to go down here and actually create the method. So public static void. This is going to be called print. As I said, print num. And we're going to send a number to the method. Okay. So then we say system.out.println. So so far basically what we're doing is we're doing this. A little bit more generically. We're going to send it a number and it's going to print that number. So the part that we need to simulate now is this next call. So what we did here is we called a different function, a different method. But what we're going to do here is we're going to call system.out. Sorry, wrong. We're going to call print num. Num plus one. Let me explain how that works. So we get print num one. We send the one down here. Num equals one. We print num which is one. Then we call the method again. But this time num plus one. So that'd be two. And then three. And then four. And then five. I'm going to go ahead and compile this and run it. Okay. And now there is an error that comes up. And just take a word for it. I don't think, yeah, I think it keeps going. So what has happened is that we have exceeded what's called the maximum recursion depth. So there's a certain amount of memory that's set aside for this to happen. And when we go over that, we have exceeded the maximum recursion depth. Now on my computer, I tested it earlier. It's around 19,000 something calls. So just again, it just ran off the screen here so we can't really tell. So we have a problem. The method of the function is not ending. So this is kind of similar to if we did like int i equals zero while, you know, while i is less than, you know, let's say three. And we do, you know, system out print line. I'm getting lazy here. I. Okay. This will run forever because we forgot to put i plus plus. It's kind of similar to that, even though the num is changing. So what we need to add here for our recursive function to correctly work is what's called a base case. And the base case is what ends. It is the ending condition. Okay. Or the condition that we'll write in this case actually keep it going. So what we can do is say if num, I can say if num is greater than two, I could do if num is not. Let's see. Well, I have in the book here, I have is not equal to three. So if the number is not equal to three, we keep calling the recursive function. But once it hits three, it should stop. Okay. And you can see that is what happened here. So let me walk you through it. One gets sent to here. Num is now one. We print one. Is one not equal to three? True. So we call it again. Num plus one is two. It's num here. Which is now two. We print two. Is two not equal to three? True. Num plus one. So now we do three. We print three. Is num not equal to three? False. Because num is equal to three. It's a little confusing. It's a negative there. So this call, like num plus one, four does not happen. So then the recursive function is finished. Now you can't see it, but it's actually going back through, they're called frames. But it's kind of going back through and then it ends. And I'm going to show you a little bit of an example of that in a few minutes. Okay. So we need to have some sort of base, we call base case, which is where it ends the function, where the function or the method has stopped calling itself. Otherwise it will just keep calling itself until we hit the maximum recursion death. So the example I want to use here is the Fibonacci sequence. So the Fibonacci sequence is like zero, one, one, two, three, I think five, eight, 13, 21, et cetera, et cetera. Okay. So this is zero. This is one. This number is zero plus one. That gives us one. This number is one plus one. This number is one plus two. This number is two plus three. You can see the pattern here three plus five, five plus eight and eight plus 13, et cetera, et cetera does continue. So the Fibonacci sequence is the sum of the previous two numbers. So hopefully that makes a little bit of sense. So what we want to do is we want to call, we want to find the Fibonacci number called Fibonam equals Fibonacci and make a method here in a minute. And let's say we want to find the eighth Fibonacci number. So system. We'll print that out. System.out.println Fibonacci. In this case, let's go ahead. I shall do it the way I had it here. So int num equals eight. Put num here for nice output. And quote plus num, just quote, quote space. Printing is kind of a pain, isn't it? Equals quote plus Fibonam. All right. Now this is where it gets interesting. So basically we're just creating a method of Fibonacci and it's going to give us this Fibonacci number. So I'm going to come down here. Now notice also that it's got to return a value. We've got to be cognizant of that. So public. Static. Int Fibonacci. Int num. So here's how it works. So this would be the third Fibonacci number. Or sorry, second. So this is the zeroth number, first number, second number. I think I have that calculated right. Where's it? Zero, one, two. Well, we'll find out in a minute. So what happens? The only exception is because zero, there's no numbers over here and there's no number minus two over here. These two are kind of our base cases. So what we would do is say if num equals zero, return zero. What else if num equals one, return one. Because we don't have an n minus one, we don't have an n minus two. Else, this is where it gets interesting. Return Fibonacci num minus two plus Fibonacci num minus one. Okay, so let me kind of try to walk you through that a little bit. So let's compile and try it first real quick and make sure it's working. Okay, so Fibonacci eight equals 21. So here's 21. So eight, seven, six, five, four, three, two, one, zero. Okay, so that's kind of what I expected. So the eighth Fibonacci number is this plus this. But how do I get this? It's this plus this. How do I get eight? It's this plus this. How do I get five? It's three plus two. How do I get three? It's two plus one. So each number, each preceding number is the sum of its, you know, its two predecessors, which is kind of interesting. Okay, so let's try and get that right. So now, but when we get to one, zero, one, it's just one. We get to zero, it's a zero. When we get to here, it's zero plus one. So number minus one, so zero, one, two. So minus two is zero, minus one is one, zero plus one is one. So each of these calls gives us the previous number plus the double previous number. I'm not sure how to say it. So let's walk through a case where we do the third zero, one, two, three. Okay, so if num is three, okay, doesn't equal zero, doesn't equal one. Okay, so we return three minus two plus three minus one, which is two. Okay, so three minus two is one. So one gives us one. So then this becomes, this evaluates to one. It's a little hard to do typing one plus Fibonacci three minus one is two. So now we have one. Now Fibonacci two, is it zero? No. Is it one? No. So Fibonacci two is Fibonacci zero. That's two minus two plus Fibonacci one, which is two minus one. So if we call, sorry, this should be plus, sorry. So Fibonacci zero gives us zero plus zero. Fibonacci one, one gives us returns one. One plus one gives us two. One plus zero plus one gives us two. So if I change this num to three up here, our third Fibonacci number is two, as you just saw. So that's basically how you trace through this type of problem. Very exciting. Again, probably want to go back and watch that a couple times. It's pretty complicated. Again, for the AP exam, typically this would be a multiple choice question where you just have to look at the code and figure out what the value is going to be. So if you break it down like I just didn't walk through it, I think you'll be able to do that pretty well. Again, hopefully throughout the course, you'll have more opportunities to practice this. And the last part is kind of really, to me, is quite interesting is the printing order. So let us do our countdown that we did before. Countdown. And I'm just going to do three. But we're going to do this recursively. Okay, so I'm going to do public static. This is going to be a void method. Countdown and int n. So we're counting down. So if n is greater than zero, let's make it a little bit more readable. Then we call countdown again. Countdown n minus one. That's a very good formatting. So we call the function recursively. Oops. And then we do else. So if we hit zero, we print out boom, system.al.println. Boom, if you remember that from previous units. And then finally down here, we do system. Okay, I forgot to put this at the beginning. So system. That's the important part here. So let's trace this one together. So we're going to count down from three to make it easy. So start with three. So num is three. Is num zero. Oh, sorry, wrong function. Is n. So we print three. Is three greater than zero? Yes. So we call countdown n minus one. So we go from here to the next method. So this is now two. We print two. Two is greater than zero. One. One. One is greater than zero. Now we've got zero. So we print zero. I think it was zero here. And then zero is not greater than zero. We print boom. And then see what happens here. Countdown. Countdown wrong. So you can see we had three, two, one, zero, boom. And in the previous example we didn't have zero. Let's leave it like this. Pretty straightforward. I think this kind of makes sense probably to most people. Now, here's what's interesting. What would happen if I put this at the end? And this is something that might come up on the AP exam. Such in a mobile choice type question. What's the output order going to be? If I compile this, let's run it. Now if you think the order is going to be three, two, one, zero, boom. You're not correct. It is boom, then zero, then one, then two, then three. Wow. How did that happen? So let's trace this one together. So n is three. It's three greater than zero. Yes it is. We call countdown again. Notice there's no printing here. So we go to the next, it's called a frame. This would be countdown two. Then we go to countdown one. Then we get the countdown zero. This is what's interesting. Remember we did three, two, one, zero. Zero is not greater than zero. We print boom. Then we print n, which in this case would be zero. This method's over. We jump back to the one. Remember we called it here. There's no else because we, this is true. It jumps down here, prints the one. Jumps back to the next, or that would be two, sorry. Jumps back to the one. This ends, comes back down, prints the one. Boom, come back and prints the zero. Oh sorry, I went the wrong way. Zero, one, two, three in my bed. So prints the zero and prints the one, prints the two, prints the three. Sorry. I will definitely try to do that more graphically when I teach this in person. But yeah, so the order is reversed because of the way the code flows. I shouldn't have a graphic for this but I don't. I'll put one in my book later when I get a chance. Anyway, so hopefully, I know it's a little confusing. I do apologize for that last one. But that is basically what you need to know for the most part for recursion. At least at least a gentle, hopefully a gentle introduction. Okay, so we looked at what recursion is. We looked at those non-recursive examples to kind of get the idea of how, you know, data flows and how numbers, you know, flow and how we call functions. Then we converted that to a simple recursive example. I showed you the maximum recursion depth and then the need for a base case. We looked at our Fibonacci example and how, you know, a big problem is a combination of sub-problems of the same type. And then we looked at the printing order and how things go in reverse depending on where the print statement is. So you got to think about how the function call works, where it is in the call, where you're at in the program at that point. Okay, so hopefully that helped more than it hurt. Good luck with that one.