DSA SheetLesson · no judge

DSA FUNDAMENTALSRECURSION BASICS

Introduction to Recursion: Calls Pause, Then Resume

Reading · 7 minQuiz · 5 questions2 code drills · run onlyGenerated by gpt-5.6-luna · Aug 13

A recursive call starts a new invocation without erasing the current one

A recursive function calls itself, but the current invocation does not disappear. It pauses at the recursive call and waits for the new invocation to finish. Each invocation has its own value of n and its own place to continue. In trace(3), the invocation with n = 3 prints its entry message, calls trace(2), and pauses before it can print its leave message.

CPPThe current invocation continues at the statement after the recursive call when the deeper call returns.
void trace(int n) {
    if (n == 0) {
        cout << "stop\n";
        return;
    }

    cout << "enter " << n << "\n";
    trace(n - 1);
    cout << "leave " << n << "\n";
}

After trace(3) calls trace(2), a new invocation starts with n = 2. The old invocation still remembers n = 3 and the next statement it must execute: cout << "leave " << n. Nothing after the call has run yet, but nothing after the call has been lost either.

CHECKPOINT 1Not answered

What happens to trace(3) when it calls trace(2)?

Checkpoints are not graded. They are here so you catch yourself before the quiz does — stuck, ask the tutor on the right.

The base case stops the chain before another recursive call begins

The calls move from trace(3) to trace(2), then trace(1), then trace(0). When n is 0, the condition n == 0 is true. trace(0) prints "stop" and returns immediately. It does not call trace(-1), because the base case decides that no deeper invocation is needed.

TEXTThe chain reaches n = 0, where the base case prevents another recursive call.
trace(3) -> trace(2) -> trace(1) -> trace(0)

trace(0): prints "stop", then returns

A base case is an ordinary condition in the function. It does not have special powers beyond choosing a different path: print "stop" and return instead of making the recursive call. Without that condition, the function would keep trying to create a deeper invocation.

the active invocations of trace(3) when trace(0) is reachedA vertical call stack contains four frames. From bottom to top they are trace(3), trace(2), trace(1), and trace(0). The first three frames are paused immediately after their recursive-call lines. Downward call arrows connect each value to the next smaller value. The trace(0) frame is active at the top, prints "stop", and makes no further call.trace(0)n = 0prints “stop”; no recursive calltrace(1)n = 1paused immediately after call to trace(0)trace(2)n = 2paused immediately after call to trace(1)trace(3)n = 3paused immediately after call to trace(2)active stack: trace(0) at the top, trace(3) waiting at the bottom
Each call keeps its own n and its own place to resume.

A paused invocation resumes after the deeper invocation returns

When trace(0) returns, the most recently paused invocation is trace(1). It resumes at the statement after trace(0), so it prints "leave 1" and returns. Then trace(2) resumes and prints "leave 2", followed by trace(3), which prints "leave 3". The leave messages appear in reverse order because the last invocation to pause is the first one able to resume.

TEXTThe entry messages follow the calls downward, while the leave messages follow the returns upward.
enter 3
enter 2
enter 1
stop
leave 1
leave 2
leave 3

The exact location of the recursive call explains the output. Each invocation pauses immediately after that line. trace(1) is closest to trace(0), so it is resumed first. Its leave statement runs before trace(2) can resume, and trace(2)'s leave statement runs before trace(3)'s. The caller is not erased, it is waiting for the call it made.

CHECKPOINT 2Not answered

What is the next output after "stop" in the execution of trace(3)?

Checkpoints are not graded. They are here so you catch yourself before the quiz does — stuck, ask the tutor on the right.

The recursive step must move every invocation toward the base case

The recursive step in trace is trace(n - 1). Starting from n = 3, each new invocation receives a smaller value: 3, then 2, then 1, then 0. This movement guarantees that the base case can eventually become true. A recursive function needs both a condition that stops and a recursive step that moves its input toward that condition.

CPPSubtracting one moves each invocation toward n == 0.
cout << "enter " << n << "\n";
trace(n - 1);
cout << "leave " << n << "\n";

If the recursive step is changed to trace(n), trace(3) calls another trace(3), which calls another trace(3), and so on. Every invocation still has n = 3, so none reaches n == 0. The calls continue creating paused invocations until the call stack runs out of space. In that case, the function never reaches the leave statement of any paused invocation.

Next part · Quiz