You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: source/ch7_recursion.ptx
+118-1Lines changed: 118 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -289,7 +289,7 @@ public class ArrayProcessor {
289
289
Neither language supports <idx> tail call optimization </idx><term>tail call optimization</term>, so the practical limits on recursion depth are a factor in both. If an algorithm requires thousands of recursive calls, an iterative (loop-based) approach is the preferred solution in both Python and Java.
290
290
</p>
291
291
<p>
292
-
The following Python code demonstrates a situation where a function calls itself indefinitely without a base case, leading to aRecursionError.
292
+
The following Python code demonstrates a situation where a function calls itself indefinitely without a base case, leading to a RecursionError.
@@ -331,4 +331,121 @@ public class ArrayProcessor {
331
331
</code>
332
332
</program>
333
333
</section>
334
+
335
+
<sectionxml:id="recursion_java_summary">
336
+
<title>Summary & Reading Questions</title>
337
+
<p><ollabel="1">
338
+
<li>
339
+
<p>Recursion solves problems by defining a <em>base case</em> and a <em>recursive step</em>; each call reduces the problem size until the base case is reached.</p>
340
+
</li>
341
+
<li>
342
+
<p>Java methods must declare visibility, static/instance context, return type, and parameter types; e.g., <c>public static int factorial(int n)</c>.</p>
343
+
</li>
344
+
<li>
345
+
<p>The recursive logic in Java mirrors Python conceptually, but Java uses curly braces <c>{}</c> and explicit types instead of indentation and dynamic typing.</p>
346
+
</li>
347
+
<li>
348
+
<p>The helper-method pattern keeps public APIs clean (e.g., <c>sumArray(int[] arr)</c>) while a private helper (e.g., <c>sumHelper(int[] arr, int index)</c>) carries extra state like the current index.</p>
349
+
</li>
350
+
<li>
351
+
<p>Closing over array bounds and indexes in the helper avoids forcing callers to provide implementation details (like a starting index).</p>
352
+
</li>
353
+
<li>
354
+
<p>Deep or unbounded recursion can exhaust the call stack: Python raises <c>RecursionError</c>; Java throws <c>StackOverflowError</c>.</p>
355
+
</li>
356
+
<li>
357
+
<p>Neither Java nor Python guarantees tail call optimization; prefer iterative solutions for algorithms requiring very deep recursion.</p>
358
+
</li>
359
+
<li>
360
+
<p>Error signaling differs across languages; for example, a Java factorial that receives a negative <c>n</c> might return a sentinel value (e.g., <c>-1</c>) after printing an error message.</p>
361
+
</li>
362
+
</ol></p>
363
+
<reading-questionsxml:id="rqs-recursion-java">
364
+
<exerciselabel="recursion-1">
365
+
<statement>
366
+
<p>Which method signature and behavior best match a typical Java recursive factorial implementation?</p>
367
+
</statement>
368
+
<choices>
369
+
<choice>
370
+
<statement><p><c>public void factorial(int n)</c> that prints each partial product and stops when <c>n</c> reaches zero.</p></statement>
371
+
<feedback><p>No. Printing results is fine for testing, but a proper factorial method should return the computed value.</p></feedback>
372
+
</choice>
373
+
<choicecorrect="yes">
374
+
<statement><p><c>public static int factorial(int n)</c> that returns <c>1</c> when <c>n <= 1</c> and otherwise returns <c>n * factorial(n - 1)</c>.</p></statement>
375
+
<feedback><p>Correct. This matches the standard recursive factorial definition in Java.</p></feedback>
376
+
</choice>
377
+
<choice>
378
+
<statement><p><c>private static int factorial(double n)</c> that repeatedly multiplies <c>n</c> and decrements it until it reaches 1.</p></statement>
379
+
<feedback><p>No. Factorials are for integers, and using <c>double</c> here is unnecessary and can cause rounding issues.</p></feedback>
380
+
</choice>
381
+
<choice>
382
+
<statement><p><c>public int factorial()</c> that uses a stored class field for <c>n</c> instead of a method parameter.</p></statement>
383
+
<feedback><p>No. Relying on a class field hides the input and makes recursion less flexible.</p></feedback>
384
+
</choice>
385
+
</choices>
386
+
</exercise>
387
+
<exerciselabel="recursion-2">
388
+
<statement>
389
+
<p>Why use a private helper method (e.g., <c>sumHelper(int[] arr, int index)</c>) behind a public method (e.g., <c>sumArray(int[] arr)</c>) in recursive array processing?</p>
390
+
</statement>
391
+
<choices>
392
+
<choice>
393
+
<statement><p>Because it allows Java to automatically optimize the recursion for faster execution.</p></statement>
394
+
<feedback><p>No. Java does not automatically optimize recursion just because you use a helper method.</p></feedback>
395
+
</choice>
396
+
<choicecorrect="yes">
397
+
<statement><p>To keep the public API simple while encapsulating extra recursion state (such as the current index) inside a private method.</p></statement>
398
+
<feedback><p>Correct. This keeps the interface clean while hiding internal details from the caller.</p></feedback>
399
+
</choice>
400
+
<choice>
401
+
<statement><p>Because public methods cannot take more than one parameter in recursive calls.</p></statement>
402
+
<feedback><p>No. Public methods can take multiple parameters; this is about interface clarity, not parameter limits.</p></feedback>
403
+
</choice>
404
+
<choice>
405
+
<statement><p>To eliminate the need for a base case by handling termination in the helper method automatically.</p></statement>
406
+
<feedback><p>No. The helper method still needs an explicit base case to stop recursion.</p></feedback>
407
+
</choice>
408
+
</choices>
409
+
</exercise>
410
+
<exerciselabel="recursion-3">
411
+
<statement>
412
+
<p>Which statement about recursion limits and errors is accurate?</p>
413
+
</statement>
414
+
<choices>
415
+
<choice>
416
+
<statement>
417
+
<p>Java can handle very deep or even infinite recursion if the method body is short and does not perform significant operations.</p>
418
+
</statement>
419
+
<feedback>
420
+
<p>No. Regardless of the method’s complexity, each recursive call consumes stack space, and infinite recursion will always cause a stack overflow.</p>
421
+
</feedback>
422
+
</choice>
423
+
<choicecorrect="yes">
424
+
<statement>
425
+
<p>When the call stack is exhausted, Python raises a <c>RecursionError</c> whereas Java throws a <c>StackOverflowError</c>, and neither language applies automatic tail call optimization.</p>
426
+
</statement>
427
+
<feedback>
428
+
<p>Correct. This difference in exception types and the lack of built-in tail call optimization is a key distinction between the two languages.</p>
429
+
</feedback>
430
+
</choice>
431
+
<choice>
432
+
<statement>
433
+
<p>Declaring a recursive method as <c>static</c> in Java reduces memory usage per call, allowing more recursive calls before a stack overflow occurs.</p>
434
+
</statement>
435
+
<feedback>
436
+
<p>No. The <c>static</c> modifier changes method context (class vs. instance) but does not meaningfully affect per-call stack memory usage.</p>
437
+
</feedback>
438
+
</choice>
439
+
<choice>
440
+
<statement>
441
+
<p>Increasing a method’s parameter type from <c>int</c> to <c>long</c> in Java can prevent stack overflows for large input values by storing bigger numbers more efficiently.</p>
442
+
</statement>
443
+
<feedback>
444
+
<p>No. The size of the number type does not influence the maximum recursion depth; stack space usage depends on the number of active calls, not numeric range.</p>
0 commit comments