Quick Sort

Say you have a big pile of exam papers to sort by marks. Doing it one swap at a time is slow. So you do something smarter. You pick one paper. Then you push every lower-mark paper to its left and every higher-mark paper to its right. Now that one paper is already in its final spot. After that you do the same trick on the left pile and on the right pile.

That is exactly what Quick Sort does. Quick Sort is a sorting method that picks one element, called the pivot, and splits the array around it. The smaller items move to its left and the bigger items move to its right. Then it sorts each side the same way.

🎯 What Problem Does It Solve?

Sorting by hand means comparing and swapping every pair. That takes a lot of work. The pain is all those repeated passes over the whole array.

Quick Sort cuts the work down. Each time it places the pivot in its correct final position. Then it only has to deal with two smaller pieces. So the big problem keeps breaking into smaller and smaller problems. This goes on until each piece is tiny and already sorted.

This idea of breaking a problem into smaller copies of itself is called divide and conquer. You divide the array, solve the small parts, and the whole thing ends up sorted.

🧩 The Pivot and the Partition

The heart of Quick Sort is one move called partition. Partition means rearranging the array around a chosen pivot. Everything smaller sits before it and everything larger sits after it.

Here is the plan in plain words:

  • Pick a pivot. We will use the last element. It is simple and works fine for learning.
  • Walk through the rest of the array from left to right.
  • Keep a marker for the boundary of the β€œsmaller than pivot” zone.
  • Every time you find an element smaller than the pivot, swap it into that zone and move the marker forward.
  • At the end, swap the pivot into the spot right after the zone. Now the pivot is in its final place.

This style of partition uses the last element as the pivot and one marker to grow the smaller zone. It is called the Lomuto partition.

πŸ” A Small Trace

Let us partition this array. The pivot is the last element, 4.

Array: [7, 2, 9, 1, 4]
Pivot: 4 (the last element)

We use a marker i that sits just before the smaller zone. It starts at -1, since there are no smaller items yet. We scan with j from the first element up to the one before the pivot.

j=0 value 7

7 not less than 4, skip

j=1 value 2

2 less than 4, swap into zone

j=2 value 9, skip

j=3 value 1, swap into zone

place pivot after zone

Let us follow the swaps step by step:

  • Start: [7, 2, 9, 1, 4], marker i = -1.
  • j = 0, value 7. Is 7 less than 4? No. Skip.
  • j = 1, value 2. Is 2 less than 4? Yes. Move i to 0, then swap positions 0 and 1. The array becomes [2, 7, 9, 1, 4].
  • j = 2, value 9. Less than 4? No. Skip.
  • j = 3, value 1. Less than 4? Yes. Move i to 1, then swap positions 1 and 3. The array becomes [2, 1, 9, 7, 4].
  • The scan is done. Now swap the pivot in the last spot with position i + 1, which is 2. The array becomes [2, 1, 4, 7, 9].

Now the pivot 4 is in its final position. Everything to its left is smaller and everything to its right is larger.

Note

After one partition the pivot is locked in place forever. We never touch it again. Quick Sort then repeats the same partition on the left part [2, 1] and the right part [7, 9].

πŸ“ Steps to Quick Sort an Array

Here is the full method, written as a recipe you can follow.

  1. If the part you are looking at has one element or none, it is already sorted. Stop.
  2. Run partition on the current part. This puts the pivot in its final position and gives you the pivot index.
  3. Apply Quick Sort to the left part, from the start up to just before the pivot.
  4. Apply Quick Sort to the right part, from just after the pivot to the end.
  5. When all parts are done, the whole array is sorted.

Steps 3 and 4 call Quick Sort again on smaller pieces. A function that calls itself like this is called recursion.

πŸ’» Quick Sort in 5 Languages

Below is Quick Sort with a Lomuto partition helper. The partition function does the rearranging and returns the pivot’s final index. The quickSort function calls itself on the left and right pieces.

quick_sort.py
# Lomuto partition: pivot is the last element
def partition(arr, low, high):
pivot = arr[high] # chosen pivot
i = low - 1 # boundary of the smaller zone
for j in range(low, high):
if arr[j] < pivot: # found a smaller element
i += 1
arr[i], arr[j] = arr[j], arr[i] # swap into zone
arr[i + 1], arr[high] = arr[high], arr[i + 1] # place pivot
return i + 1 # pivot index
# Recursively sort the array
def quick_sort(arr, low, high):
if low < high:
p = partition(arr, low, high)
quick_sort(arr, low, p - 1) # sort left part
quick_sort(arr, p + 1, high) # sort right part
arr = [7, 2, 9, 1, 4]
quick_sort(arr, 0, len(arr) - 1)
print(arr)

The output of the above code will be:

Output
[1, 2, 4, 7, 9]

Tip

Partition does the real work. Quick Sort itself is just β€œpartition, then call yourself on the two halves.” If you understand partition, you understand Quick Sort.

⏱️ How Fast Is It?

The speed of Quick Sort depends a lot on the pivot you pick. The very same algorithm can be fast or slow. It comes down to luck and to how you choose the pivot.

When the pivot lands near the middle each time, the array splits into two near-equal halves. That gives O(n log n) time, which is fast. This is the average case and the best case.

The bad case is when the pivot is always the smallest or the largest element. Then one side is empty and the other side holds everything. The array shrinks by just one each time, which gives O(n^2) time. This happens, for example, when you use the last-element pivot on an array that is already sorted.

Caution

Pivot choice matters a lot. A common fix is to pick a random element as the pivot, or to use the median of the first, middle, and last elements. This makes the slow O(n^2) case very unlikely on real data.

Quick Sort sorts the array in place, so it does not need a second array. But recursion uses the call stack, and that needs about O(log n) space when the splits are balanced.

One more thing. Quick Sort is not stable. Stable means equal elements keep their original order. Quick Sort can swap equal elements past each other, so their order may change.

Here is the full picture.

Case Time Complexity When It Happens
Best O(n log n) Pivot splits the array into even halves
Average O(n log n) Typical mixed data
Worst O(n^2) Pivot is always smallest or largest
Space O(log n) Recursion call stack, balanced splits

⚠️ Common Mistakes

A few small slips trip up almost everyone the first time.

  • Starting the marker i at low instead of low - 1. Then the very first smaller element lands in the wrong spot.
  • Forgetting the final swap that places the pivot. Without it, the pivot never reaches its correct position.
  • Recursing with the wrong bounds. The left call goes up to p - 1 and the right call starts at p + 1. If you include p again, it can loop forever.
  • Always using the last element as the pivot on sorted data. That triggers the slow O(n^2) case. Pick a random pivot to stay safe.
  • Missing the base case low < high. Without it the recursion never stops.

🧩 What You’ve Learned

  • βœ… Quick Sort picks a pivot, partitions the array around it, then sorts the two sides.
  • βœ… Partition pushes smaller elements left and larger ones right, then locks the pivot in its final place.
  • βœ… The Lomuto partition uses the last element as pivot and one marker to grow the smaller zone.
  • βœ… Quick Sort runs in O(n log n) on average but can drop to O(n^2) with bad pivots.
  • βœ… It sorts in place, uses about O(log n) stack space, and is not stable.
  • βœ… Picking the pivot well, with a random pivot or the median of three, keeps the slow case away.

Check Your Knowledge

Test what you learned. Pick an answer for each question, then click Check.

  1. 1

    What does the partition step do?

    Why: Partition places the pivot in its final spot, with smaller elements before it and larger ones after it.

  2. 2

    In the Lomuto partition shown, which element is chosen as the pivot?

    Why: This Lomuto version uses the last element of the current part as the pivot.

  3. 3

    What is the average time complexity of Quick Sort?

    Why: On typical data the pivot splits the array fairly evenly, giving O(n log n).

  4. 4

    When does Quick Sort hit its worst case of O(n^2)?

    Why: A consistently smallest or largest pivot leaves one side empty, so the array shrinks by only one each time.

πŸš€ What’s Next?

Share & Connect