CS Atlas GATE 2027
PDS course
0 / 103 complete

PDS/Phase 2 · Recursion

Lesson 2.1.2 · Item 37 of 103

Recursion trees; counting calls; work done before vs after the recursive call

Read at your own pace. Try the questions before opening the answers.

On this page

0 · Recall Warm-up

Answer from memory first. Answers are in the Answer Vault at the bottom.

  • What two parts must every recursive function have? from Lesson 2.1.1
  • What does free(p) do to p itself? from Lesson 1.7
  • How many times does count++ run in for (i = 1; i <= 16; i *= 2) for (j = 1; j <= i; j++) count++;? from Lesson 1.2.2

1 · The Hook

🎣

A family invitation goes out: each person invites their two children, who each invite their two children. From one person, the invitations spread into a branching diagram, like a family tree drawn upside down. When a recursive function calls itself twice, its calls branch the same way, and the number of calls can grow very fast.

2 · Predict First

🤔

What does this print?

void p(int n)
{
    if (n == 0)
        return;
    printf("%d ", n);     /* before the call: on the way down */
    p(n - 1);
    printf("%d ", n);     /* after the call: on the way back up */
}

int main(void)
{
    p(3);
    printf("\n");
    return 0;
}

Make a guess in your head. The answer opens Section 3.

3 · Core Concept

💡

Predict First — the answer

Output

3 2 1 1 2 3

The first printf runs on the way down (3, 2, 1). The second runs after the inner call has finished, on the way back up, so the same numbers appear in reverse (1, 2, 3).

Before vs after the recursive call

Code before the recursive call runs in the order of the calls (going down). Code after it runs in reverse order (coming back up). That is why the same printf placed before or after the call prints a number forwards or backwards:

void show(int n)
{
    if (n == 0)
        return;
    show(n / 10);
    printf("%d", n % 10);
}

void showRev(int n)
{
    if (n == 0)
        return;
    printf("%d", n % 10);
    showRev(n / 10);
}

int main(void)
{
    show(2027);
    printf(" ");
    showRev(2027);
    printf("\n");
    return 0;
}

Output

2027 7202

Recursion trees

A recursion tree draws every call as a box. Each call’s box is connected to the boxes of the calls it makes, below it. The top box is the first call; boxes with no calls below them are base cases. Reading the boxes level by level shows how much work there is.

Two calls per call: Fibonacci

The Fibonacci numbers 0, 1, 1, 2, 3, 5, 8, … are defined by fib(0) = 0, fib(1) = 1, fib(n) = fib(n − 1) + fib(n − 2). Written directly as recursion, every call (except the base cases) makes two calls:

int calls = 0;

int fib(int n)
{
    calls++;
    if (n <= 1)
        return n;
    return fib(n - 1) + fib(n - 2);
}

int main(void)
{
    int v = fib(5);
    printf("fib(5) = %d, calls = %d\n", v, calls);
    return 0;
}

Output

fib(5) = 5, calls = 15

The number of calls C(n) satisfies C(n) = 1 + C(n − 1) + C(n − 2), with C(0) = C(1) = 1: C(4) = 9, C(5) = 15, C(6) = 25. It grows almost as fast as doubling, because the same values are recomputed again and again (fib(3) is computed twice inside fib(5)).

Counting calls and output

To count calls: draw the tree, or write a counting rule like C(n) = 1 + (calls made by the recursive part) and fill a table from small n upwards. Each call’s printf runs once, so the number of printed items equals the number of calls that reach that printf.

void g(int n)
{
    if (n <= 0)
        return;
    g(n - 1);
    printf("%d ", n);
    g(n - 1);
}

int main(void)
{
    g(3);
    printf("\n");
    return 0;
}

Output

1 2 1 3 1 2 1

g(n) prints 2^n^ − 1 numbers: P(n) = 2P(n − 1) + 1, P(0) = 0 (Lesson 0.2.2’s doubling sum).

Depth vs number of calls

Depth is the number of levels in the drawing (the longest chain from the top box down); the number of calls is the number of boxes. fib(5) has 15 calls but depth only 5 (fib(5) → fib(4) → fib(3) → fib(2) → fib(1)).

4 · Visual

Diagram: f(1) · f(0) · f(2) · f(1) · f(3) · f(1) · f(0) · f(2) · f(4)

Recursion tree of fib(4): 9 calls (boxes). Green boxes are base cases. fib(2) is computed twice — the source of the waste.

Recursion tree of g(3) (g calls g(n-1), prints n, calls g(n-1)):

                     g(3)
            /         |         \
         g(2)      print 3      g(2)
        /  |  \                /  |  \
     g(1) p2  g(1)          g(1) p2  g(1)
    / | \     / | \        / | \     / | \
  g0 p1 g0  g0 p1 g0     g0 p1 g0  g0 p1 g0

 printed left to right: 1 2 1 3 1 2 1     (2^3 - 1 = 7 numbers)

Reading the prints in the order they happen gives the output.

5 · Worked Examples

Example 1 Easy

What does this print?

void p(int n)
{
    if (n == 0)
        return;
    printf("%d ", n);     /* before the call: on the way down */
    p(n - 1);
    printf("%d ", n);     /* after the call: on the way back up */
}

int main(void)
{
    p(3);
    printf("\n");
    return 0;
}

Solution

Down: 3 2 1. Up: 1 2 3.

Output

3 2 1 1 2 3

Example 2 Medium

How many calls does fib(6) make in the program above (counting the first call)?

Solution

C(0) = C(1) = 1; C(2) = 1 + 1 + 1 = 3; C(3) = 1 + 3 + 1 = 5; C(4) = 9; C(5) = 15; C(6) = 1 + 15 + 9 = 25.

Example 3 GATE

What does this print, and how many calls of h are made (including those with n < 1)?

void h(int n)
{
    if (n < 1)
        return;
    h(n - 2);
    printf("%d ", n);
    h(n - 1);
}

int main(void)
{
    h(3);
    printf("\n");
    return 0;
}

Solution

h(3): h(1) first → [h(−1) returns, print 1, h(0) returns]; print 3; then h(2) → [h(0) returns, print 2, h(1) → [h(−1), print 1, h(0)]]. Output: 1 3 2 1. Calls: H(n) = 1 + H(n − 2) + H(n − 1) with H(n) = 1 for n < 1: H(1) = 3, H(2) = 5, H(3) = 1 + 3 + 5 = 9.

Output

1 3 2 1

6 · GATE Traps

⚠️

  • Printing after the recursive call reverses the order.
  • Count calls including the base-case calls (the leaves of the tree).
  • Depth ≠ number of calls.
  • Two recursive calls per call can make the number of calls grow exponentially.
  • With two calls, the second call starts only after the first has completely finished (the whole left part of the tree first).

8 · Memory Hook

🧠

“Down the stairs, then back up.” Work before the call happens on the way down, work after it on the way up. Two calls per step and the stairs become a branching family tree.

9 · Connect the Dots

Lesson 2.1.1 traced one chain of calls; recursion trees show branching calls and let us count them. With the tracing tools in place, the next lesson answers: what are the classic recursive programs GATE expects you to know (factorial, Fibonacci, the greatest common divisor, power, a famous disk-moving puzzle), and why does each one stop?

10 · Self-Test

GATE format. Try every question before opening the vault.

Q1MCQ1 markOrder

What does this print?

void g(int n)
{
    if (n <= 0)
        return;
    g(n - 1);
    printf("%d ", n);
    g(n - 1);
}

int main(void)
{
    g(3);
    printf("\n");
    return 0;
}
  • (A) 1 2 1 3 1 2 1
  • (B) 3 2 2 1 1 1 1
  • (C) 1 2 3
  • (D) 3 2 1 1 2 3

Q2NAT2 marksCounting calls

Using C(n) = 1 + C(n − 1) + C(n − 2) with C(0) = C(1) = 1, how many calls does fib(7) make?

Numerical answer: ________

Q3MCQ2 marksOutput

What does this print?

void h(int n)
{
    if (n < 1)
        return;
    h(n - 2);
    printf("%d ", n);
    h(n - 1);
}

int main(void)
{
    h(3);
    printf("\n");
    return 0;
}
  • (A) 3 1 2 1
  • (B) 1 3 2 1
  • (C) 1 2 3
  • (D) 1 3 1 2

Q4NAT1 markPrints

How many numbers does g(5) print, where g prints n between two calls of g(n − 1) and g(0) prints nothing?

Numerical answer: ________

Q5MSQ1 markTrees

In a recursion tree, which are true?

  • (A) The top box is the first call.
  • (B) The boxes with no calls below them are base cases.
  • (C) Each box is one call.
  • (D) The number of boxes equals the recursion depth.

11 · Rule Card

  • Before the call: runs going down (call order). After the call: runs coming back (reverse order).
  • Recursion tree: one box per call; base cases at the bottom; top = first call.
  • Calls with two branches: C(n) = 1 + C(left) + C(right); fill a table bottom-up.
  • fib calls: 1, 1, 3, 5, 9, 15, 25, 41 for n = 0…7.
  • Two calls of n − 1 each: 2ⁿ − 1 prints; depth n.

12 · Concept Ledger

Unlocked in this lesson. From here on, these terms may be used.

recursion treenumber of callswork before / after the recursive callFibonacci (recursive)repeated subproblems

13 · Answer Vault

Answer Vault

Try the questions first. Open when you are ready to check.

Recall Warm-up

  • A base case and a recursive case that moves towards it.
  • Nothing: p keeps the old (now dangling) address.

Self-Test

Q1 Answer: (A)1 mark

Left calls finish first; n prints between the two calls.

Output

1 2 1 3 1 2 1
  • (B) is wrong: n is printed between the calls, not before.
  • (C) is wrong: Each g(n) contains two g(n − 1).
  • (D) is wrong: That is the before/after pattern with one call.

Re-read: Lesson 2.1.2 — Recursion trees; counting calls; work done before vs after the recursive call

Q2 Answer: 412 marks

C(6) = 25, C(5) = 15: 1 + 25 + 15 = 41.

Re-read: Lesson 2.1.2 — Recursion trees; counting calls; work done before vs after the recursive call

Q3 Answer: (B)2 marks

Trace in Example 3.

Output

1 3 2 1
  • (A) is wrong: h(n − 2) runs before printing n.
  • (C) is wrong: h(3) prints 1 from h(1) first.
  • (D) is wrong: h(2) prints 2 before its own h(1).

Re-read: Lesson 2.1.2 — Recursion trees; counting calls; work done before vs after the recursive call

Q4 Answer: 311 mark

P(n) = 2P(n − 1) + 1 → 2⁵ − 1 = 31.

Re-read: Lesson 2.1.2 — Recursion trees; counting calls; work done before vs after the recursive call

Q5 Answer: (A) (B) (C)1 mark

Depth is the longest chain, not the number of boxes.

  • (D) is wrong: Depth is the longest chain of calls, not the count.

Re-read: Lesson 2.1.2 — Recursion trees; counting calls; work done before vs after the recursive call

Ready for the next idea?

Mark this item complete when you’ve finished reading and working through it.