1

I have this code and I was just wondering is my understanding of it correct.

5 is passed into the method numbers and n now equals 5. The if statement is false and therefore it does the else statement, and does numbers(5-1) and does the method numbers again and does NOT print out n or return yet.

Now n = 4 and the same method is repeated till n = 1 at which point it hits return? and so from this point it returns to where n = 2, follows the prints 2 (System.out part) and then returns, at which point it returns to n = 3, prints 3 and returns..and so on all the way to 5?

That is what i think is going on, could someone clarify this for me please, thank you!

public class test {

    public static void main(String [] args){

        numbers(5);
    }

    public static void numbers (int n){

        if(n==1) return;
        else{
            numbers(n-1);
            System.out.println(n);
            return;
        }
    }
}
user3562135
  • 159
  • 2
  • 9
  • 1
    Seems like your understanding is right on -- but what happens when `n < 0` ? :) – C.B. Apr 30 '14 at 21:17
  • 2
    Your `else {` and the `return` inside the `else {` is redundant. – Bhesh Gurung Apr 30 '14 at 21:19
  • @C.B. it can never each n < 0 because it returns when n == 1 and ends? – user3562135 Apr 30 '14 at 21:21
  • @user3562135 it can if you call it with `numbers(0)`. Generally it is best practice to cover all possible cases when you code functions. – DRAX Apr 30 '14 at 21:24
  • Oh lol, i'm guessing it'll go on forever or something? This code was given by my teacher for recursion i was just trying to understand it, its not really meant to be used for anything – user3562135 Apr 30 '14 at 21:25
  • 1
    That is correct, it will run forever (stackoverflow :)) – DRAX Apr 30 '14 at 21:26
  • Ah thats useful to know and thanks for point it out! :D – user3562135 Apr 30 '14 at 21:28
  • Won't necessarily run forever, if your stack is big enough. ;) It _could_, in theory, run until `n` overflows to `Integer.MAX_VALUE`, and then keep going down until it hits 1. I'm also not sure if there's anything in the JLS that prevents [tail call optimization](http://en.wikipedia.org/wiki/Tail_call), in which case you can recurse forever without hitting a stackoverflow. (But in practice, on any system that's out there, yes, it'll stackoverflow.) – yshavit Apr 30 '14 at 21:29
  • Your method name should describe what it does. Rename "numbers" to "countdown" or some-such. – MirroredFate Apr 30 '14 at 21:33
  • 1
    You can avoid the endless recursion until stack overflow by changing the condition to `if (n <= 1) return;`. In general it's safer to test for inequalities rather than strict equalities. – pjs Apr 30 '14 at 21:36
  • 2
    Possible duplicate of [Understanding how recursive functions work](http://stackoverflow.com/questions/25676961/understanding-how-recursive-functions-work) –  May 27 '16 at 18:47

3 Answers3

1

Your understanding is correct. You can verify this yourself by stepping through the code in a debugger.

meriton
  • 68,356
  • 14
  • 108
  • 175
0

Your understanding and code is correct. All I would suggest is there is no need to use the return statement in the else block because you have proper terminating condition. So after modification you code would be like this.

public class test{
    public static void main( String[] args )
    {
       numbers(5);
    }

    public static void numbers (int n){

        if(n==1) return;
        else{
            numbers(n-1);
            System.out.println(n);
        }
    }
}
Ashish
  • 14,295
  • 21
  • 82
  • 127
0

ps (pre-script)

I've left the code unclean to make as little change to the OP's code as possible. For extra credit, you can try to simplify any/all of the above examples, so that they don't use both if and else block, but simply have one if block, while also getting rid of all the return statements.

Good luck, and have fun with coding. :)


Yup, your understanding is correct.

However one clarification

I think you know this already, but your code won't print 1. It'll print:

2
3
4
5

If you want to print 1 also, then you can fix this in 3 different ways

Method 1

Change n==1 condition to n==0. This is what I'd do. It's the simplest and seems most natural to me.

public static void numbers (int n){

    if(n==0) return;
    else{
        numbers(n-1);
        System.out.println(n);
        return;
    }
}

Method 2

Move the print before the conditional

public static void numbers (int n){

    System.out.println(n);
    if(n==1) return;
    else{
        numbers(n-1);
        return;
    }
}

Now you can probably guess that this will print the numbers as

5
4
3
2
1

Method 3

Execute print in both cases, but after the if block, not before

public static void numbers (int n){

    if(n==1){
        // Do nothing, Don't return yet.
        //return;
    } else{
        numbers(n-1);
        // Don't return yet.
        //return;
    }
    System.out.println(n);
}

ps

  • what meriton said about using debugger, debugger is your friend. And when coding I recommend using Eclipse or IntelliJ IDEA. I have only used Eclipse for many years but since Google seems to be moving towards IntelliJ IDEA for it's Android Development, it might be worth a shot too.
Spundun
  • 3,936
  • 2
  • 23
  • 36
  • An empty `if` clause? Yucko! Much cleaner to just do `if (n > 1) { numbers(n-1); }` followed by your `println`. – pjs Apr 30 '14 at 21:39
  • I agree, I was trying to change as little of the code as possible. I left the cleanup for the OP as an extra credit. Mentioned as a PS. May be I should move that to the top. – Spundun Apr 30 '14 at 21:40