Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Since your example method is tail-recursive, translating it to iterative style is easy and does not even require an explicit stack.</p> <p>Here are some steps that can be applied to any recursive function:</p> <p><strong>Step 1</strong>: Rewrite the method so it calls itself exactly once (your method already does this), has exactly one <code>return</code> statement, and uses <code>if</code> and <code>goto</code> instead of <code>else</code>, <code>while</code>, <code>for</code> and <code>foreach</code>:</p> <pre><code>int gcd(int m, int n) { int result; if (n == 0) { result = m; goto done; } result = gcd(n, m % n); done: return result; } </code></pre> <p><strong>Step 2</strong>: Replace the recursive call with the assignment of the new arguments to the parameters and a <code>goto</code> to the start of the method:</p> <pre><code>int gcd(int m, int n) { int result; start: if (n == 0) { result = m; goto done; } int old_m = m; m = n; n = old_m % n; goto start; done: return result; } </code></pre> <p>If the method was not tail-recursive, the method would need to save its state before the <code>goto</code> and restore it later again.</p> <p><strong>Step 3</strong>: Remove the <code>goto</code>s again:</p> <pre><code>int gcd(int m, int n) { int result; while (true) { if (n == 0) { result = m; break; } int old_m = m; m = n; n = old_m % n; } return result; } </code></pre> <p><strong>Step 4</strong>: Make the method look nicer:</p> <pre><code>int gcd(int m, int n) { while (n != 0) { int old_m = m; m = n; n = old_m % n; } return m; } </code></pre> <hr> <p>Here's an example that is not tail-recursive:</p> <pre><code>int fac(int x) { if (x == 0) { return 1; } return x * fac(x - 1); } </code></pre> <p><strong>Step 1:</strong></p> <pre><code>int fac(int x) { int result; if (x == 0) { result = 1; goto end; } result = x * fac(x - 1); end: return result; } </code></pre> <p><strong>Step 2:</strong></p> <pre><code>int fac(int x) { Stack&lt;int&gt; stack = new Stack&lt;int&gt;(); int result; start: if (x == 0) { result = 1; goto end; } stack.Push(x); x = x - 1; goto start; end: if (stack.Count != 0) { x = stack.Pop(); result = x * result; goto end; } return result; } </code></pre> <p><strong>Step 3:</strong></p> <pre><code>int fac(int x) { Stack&lt;int&gt; stack = new Stack&lt;int&gt;(); int result; while (true) { if (x == 0) { result = 1; break; } stack.Push(x); x = x - 1; } while (stack.Count != 0) { x = stack.Pop(); result = x * result; } return result; } </code></pre> <p><strong>Step 4:</strong></p> <pre><code>int fac(int x) { Stack&lt;int&gt; stack = new Stack&lt;int&gt;(); while (x != 0) { stack.Push(x); x = x - 1; } int result = 1; while (stack.Count != 0) { x = stack.Pop(); result = x * result; } return result; } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload