GeeksforGeeks Medium

Sort a Stack

Sort a stack using only stack operations and recursion — no arrays, no loops over indices.

stackrecursion
Open on GeeksforGeeks ↗
02

Intuition

Pop everything (recursion holds the elements in call frames), then insert each element back in sorted position — again recursively: pop while the top is bigger, drop the element, push everything back.

How to spot this pattern

The constraint is the puzzle: no arrays, no extra containers — only stack operations. When the only storage you're allowed is the call stack, recursion becomes the data structure. The shape is always the same: pop one item, solve the smaller problem, then re-insert the held item correctly on the way back up. Reversing a stack works identically.

03

Approach

1

Peel with recursion

sort(): pop top, sort the rest, then insert the popped element into the now-sorted stack.

2

Sorted insert, also recursive

insert(x): if stack empty or top ≤ x, push x. Otherwise pop, insert(x) deeper, re-push.

3

Cost

Each insert may touch the whole stack → O(n²) moves, O(n) recursion depth. It's an exercise in recursion, not efficiency.

04

Solution & live demo

1def sorted_insert(stack, x):
2 if not stack or stack[-1] <= x:
3 stack.append(x)
4 return
5 top = stack.pop()
6 sorted_insert(stack, x)
7 stack.append(top)
8 
9def sort_stack(stack):
10 if stack:
11 top = stack.pop()
12 sort_stack(stack)
13 sorted_insert(stack, top)
14 return stack
05

Common pitfalls

Pushing the held element back before recursing

✗ Wrong
top = stack.pop()
stack.append(top)
sort_stack(stack)
✓ Right
top = stack.pop()
sort_stack(stack)
sorted_insert(stack, top)

Putting it straight back leaves the stack exactly as it was, so the recursion never shrinks the problem and never terminates. The held element has to stay out — in the call frame — while the rest is sorted, and only then be inserted into its correct place.

Appending in sorted_insert without unwinding first

✗ Wrong
def sorted_insert(stack, x):
    stack.append(x)
✓ Right
if not stack or stack[-1] <= x:
    stack.append(x)
    return
top = stack.pop()
sorted_insert(stack, x)
stack.append(top)

A stack only exposes its top, so an element that belongs deeper can't be placed directly. You lift off everything larger, drop the value in, then push the lifted items back — that unwinding is the insertion.

Using < and infinitely recursing on duplicates

✗ Wrong
if not stack or stack[-1] < x:
✓ Right
if not stack or stack[-1] <= x:

With two equal values neither can settle above the other: the guard keeps failing, the value is lifted and reinserted forever. Allowing equality lets a duplicate rest on its twin and the recursion bottoms out.

06

Edge cases

Already sorted stack

Every insert hits the top ≤ x case immediately — O(n) total.

Duplicates

≤ comparison keeps them adjacent, insertion stable.

07

Complexity

Time
O(n²)
Space
O(n)
Call stack replaces the auxiliary array.