Recursion and divide and conquer
A recursive function solves a problem by calling itself on a smaller version of it. It needs two parts: a base case that answers directly (an empty list is sorted) and a recursive step that shrinks the input and combines the results. Divide and conquer is the most common shape: split the input into pieces, solve each piece recursively, then combine.
The running time satisfies a recurrence. If you split into subproblems of size and spend splitting and combining, then , and the master theorem reads off the answer by comparing with :
Three recurrences come up again and again. Merge sort is : here , so . Binary search is : , so . A routine that makes one linear pass and then recurses into only one half is : , so , because the work shrinks geometrically ().
One practical limit in Python: the default recursion depth is 1000. Halving recursion on a million elements goes about 20 levels deep and is fine. Recursion that peels off one element at a time on elements raises RecursionError, so write that version as a loop.