Linked List · Medium

250. Quicksort on a Linked List

Topics: Linked List, Sorting

Solve it on DeVert Campus - free code runner

Problem

A singly linked list contains n integer values in no particular order. Sort it using the quicksort algorithm (pick a pivot, partition the list around it, then recursively sort the partitions) and print the sorted values.

Input and output

Input: The first line contains an integer n. The second line contains n space-separated integers, the linked list's values in order. Output: Print the sorted values, space-separated, on one line.

Example

Input:
5
5 3 4 1 2
Output:
1 2 3 4 5

Constraints

1 <= n <= 10^5

Key observation

Picking the LAST or FIRST node as pivot (rather than some 'middle' element, which isn't O(1) accessible in a linked list) is a necessary adaptation - this makes worst-case behavior (O(n²)) more likely on already-sorted or adversarial inputs compared to array quicksort with a randomized pivot.

Intuition

Sort a linked list using the quicksort algorithm, adapted to work without array indexing. Brute force: Copy all values into an array, quicksort the array using standard index-based swapping, and rebuild the list - this works but doesn't demonstrate adapting quicksort's PARTITIONING step to work without random access, which is the actual point of this exercise. Optimised: Building explicit 'less than' and 'greater or equal' sub-lists (by relinking nodes as you scan, rather than swapping elements by index) replicates quicksort's partitioning logic in a way that works naturally on linked lists, which have no O(1) random access needed for typical index-based partitioning.

Approach 1

Traverse the linked list once to copy all its values into an array, sort that array with a standard efficient sort, then rebuild a new linked list (or overwrite the existing nodes' values) from the sorted array in list order. This produces a correct sorted list but requires an entire auxiliary array the size of the list, which sidesteps rather than embraces the linked-list structure. Time: O(n log n) average Space: O(n)

Better - List Quicksort with Fixed Pivot

Perform quicksort natively on the linked list: pick the first node as the pivot, then walk the rest of the list splitting nodes into a 'less than pivot' list and a 'greater than or equal to pivot' list by relinking pointers (no array conversion, no new node allocation), recursively sort each sublist the same way, and concatenate less-list + pivot + greater-list. This works directly on pointers and avoids the full array copy, but a fixed first-element pivot degrades badly (to quadratic time) on already-sorted or adversarially ordered lists. Time: O(n log n) average, O(n^2) worst case Space: O(log n) recursion stack

Optimal - List Quicksort with Randomized Pivot

Use the same in-place pointer-relinking partition scheme as the better approach, but select the pivot randomly (or via median-of-three sampling of a few nodes) instead of always taking the first node. This makes the O(n^2) worst case extremely unlikely regardless of the input's original order, since an adversary can no longer predict which element will be chosen as pivot, giving expected O(n log n) performance robustly even on already-sorted input where the fixed-pivot version would be at its worst. Time: O(n log n) expected Space: O(log n) recursion stack

Step by step

1. Pick a PIVOT node (commonly the last or first node of the current sub-list, since a linked list has no convenient 'middle' index access). 2. Partition by building TWO sub-lists - one for values LESS than the pivot, one for values GREATER OR EQUAL - by relinking nodes into each, rather than swapping array elements. 3. Recursively sort each sub-list, then relink them around the pivot node to form the final sorted result.

Complexity

Time: O(n log n) average case, O(n²) worst case (e.g. with an already-sorted list and a poor pivot choice) - the same complexity profile as array-based quicksort. Space: O(log n) average recursion depth, O(n) worst case.

Edge cases

n = 1 (trivially sorted); n = 10^5 for performance; already-sorted or reverse-sorted input, and repeated values, since the constraints don't rule out duplicates.

Interview tip

Be ready to explain explicitly WHY quicksort's usual advantage (fast in-place swaps by array index) doesn't apply to linked lists - this is exactly why merge sort is generally preferred for linked lists in practice, despite quicksort often being faster on arrays.

All DSA problems