Keep an array unchanged, and sum entries in the half-open integer interval of array indices . The precondition requires integers and exact, terminating integer addition. An empty range returns the empty sum zero; a one-entry range returns that entry. Every longer range splits at its middle array index:
S(A, l, r):
    require integer indices with 0 <= l <= r <= length(A)
    size = r - l
    if size == 0:
        return 0
    if size == 1:
        return A[l]
    middle = l + floor(size / 2)
    left_sum = S(A, l, middle)
    right_sum = S(A, middle, r)
    return left_sum + right_sum
For the original array , call . The left half returns , the right half returns , and the original invocation returns . The right half's left endpoint increases from zero to two: what decreases is range length , not every argument. Negative entries affect the answer but do not affect algorithm termination.
Figure 1.
Seven calls compute an array sum with only three frames active at once
. Original binary tree of invocations for , with integer intervals labeling ranges and upward arrows labeling returned sums. Small numbers give the order in which invocations begin when the left child runs first. The highlighted graph path contains the three active stack frames while the entry is read; the result from the completed left sibling is retained by its parent. Details.
For range length , the children have lengths and , both positive and strictly less than . The floor function chooses the split; the ceiling function gives the other length. Algorithm termination follows by this natural number measure. For algorithm correctness, apply mathematical induction on : the two base cases return the specified sum; for a larger range, the two disjoint child ranges cover every original array index exactly once, so addition of their correct sums gives the required sum.
For , the invocation tree is a full binary tree with leaves, one per array entry. If is its number of nonleaf vertices, counting edges gives , so . Thus the total invocation count is , and there are combining additions. Here gives seven calls and three combining additions. For , there is one call and no combining addition; for , there is also one call and no combining addition, but no entry leaf, so the formula does not apply.
The call stack holds the active branch, rather than the entire invocation tree. Execute the left child completely before the right child, retaining the left result in the parent stack frame. The maximum number of active stack frames is for , and one for . Balanced splitting therefore needs frames for , compared with the frames of the factorial recursive process. Assuming constant-cost array access, index operations and addition, its time complexity is and its auxiliary space complexity is machine words for , excluding the stored input. Pass the same array with different endpoints, rather than copying slices. These bounds require all stored indices and partial sums to fit in a constant number of machine words; exact unbounded integer addition and storage require a separate bit cost analysis.
For a natural number , the factorial satisfies and for . The following description includes the zero base case explicitly; a negative or nonintegral input is outside its precondition:
F(n):
    require n is an integer and n >= 0
    if n == 0:
        return 1
    child_result = F(n - 1)
    return n * child_result
For , the arguments on descent are . Each positive-argument invocation postpones one multiplication until its recursive call returns. At the deepest point, the call stack has five stack frames: four suspended callers and the active zero base case. The invocation at zero returns to the invocation at one, rather than finishing the entire computation. Returns then give
A stack frame retains the caller's argument and where to resume. When the invocation at three receives , it uses its own , obtains , and returns that value to the invocation at four. The recursive calls share a definition, but their local variables belong to separate invocations.
Figure 1.
Factorial descent builds pending work; returning frames complete it
. Original trace of with base case . The central snapshot shows all five stack frames at maximum depth. Downward arrows create recursive calls; upward arrows carry completed answers to suspended callers. A return removes only the completed invocation's stack frame. Details.
The natural number measure decreases by one on every recursive call, so algorithm termination follows. For algorithm correctness, use mathematical induction: the zero base case returns ; assuming the child's answer is , the caller returns . This also explains why keeping the caller's matters.
There are exactly invocations and multiplications, including one invocation and no multiplications when . Ordinary execution of this recursive process uses at most active stack frames, hence frames for in Big O notation. If each test, call, subtraction and multiplication is counted as constant cost, its time complexity is . That is an arithmetic-operation model: exact arbitrary-length integer multiplication has growing cost, and neither the factorial output nor every stack frame's numeric contents occupies a universally fixed number of bits.
Stack frame 2026-10-18
The record for one active invocation in a call stack, containing information such as local variables and the place to resume its caller. Returning removes that invocation's stack frame, allowing the caller's computation to continue.