The Algorithm
A. M. Andrew's 1979 variant of Graham scan replaces the polar-angle sort with a plain coordinate sort, at the cost of scanning twice instead of once:
- Sort all points by $(x, y)$ — a numeric sort, no trigonometry, no choice of pivot.
- Build the lower hull: scan left to right, maintaining a stack with the same left-turn rule as Graham scan.
- Build the upper hull: scan right to left (or equivalently, reverse the sorted list), maintaining a fresh stack with the same rule.
- Concatenate the lower and upper hulls (dropping the duplicated first/ last points where they meet) to get the full hull in order.
Core Insight: the "drop the duplicated endpoint" step is not an edge case to special-case away — the lower hull's last point is the upper hull's first point (the rightmost point of the set) by construction, and symmetrically for the leftmost point. Concatenating without dropping would silently duplicate two vertices in the output.
Why Prefer This Over Graham Scan
Both algorithms are $O(n \log n)$ and share the identical stack invariant, so the choice is mostly about implementation ergonomics: monotone chain avoids the pivot-selection special case and the angle-comparator function entirely, at the cost of running the scan twice. In practice this makes monotone chain the more common choice in competitive programming and production libraries, precisely because a plain sort() call is harder to get wrong than a custom polar-angle comparator.
Trace It Yourself
Run monotone_chain on [(0,0), (4,0), (4,4), (0,4), (2,2), (2,-1)] — the same input used in the Graham scan trace. Confirm both algorithms agree on the same 5-vertex hull, in possibly different starting order but the same cyclic sequence.