Simulating QuickSort on 25, 36, 12, 4, 5, 16, 58, 54, 24, 16, 9, 65, 78 (Lomuto Partition)
QuickSort is a divide-and-conquer sorting algorithm that chooses a pivot and then partitions the array into two subarrays: elements less than the pivot and elements greater than (or equal to) the pivot. It then recursively applies the same idea to each subarray until subarrays have size 0 or 1. Its typical performance is on average, with worst-case if the pivot choices are poor. 2
This section simulates QuickSort step-by-step for the given input using the Lomuto partition scheme (pivot = last element). Lomuto partition is widely used in introductory materials and has a simple loop/invariant style. 2
We will use these keywords:
- pivot
- partition
- recursive
- in-place
Footnotes
-
Quicksort - Wikipedia - Describes quicksort as divide-and-conquer with pivot partitioning and notes average , worst-case , and instability. ↩
-
Quicksort - Wikipedia (complexity table details) - Contains best/average/worst-case complexity statements. ↩
-
Lomuto Partition Algorithm - GeeksforGeeks - Step-by-step Lomuto partition with last element as pivot and swapping into pivot position. ↩
-
Quicksort - Wikipedia (Lomuto partition scheme description) - Details Lomuto-style invariants and pivot placement behavior for the scheme. ↩
Quick Sort | Part 1: Lomuto Partitioning Scheme
Lomuto partition rule (what we simulate)
Given a subarray , Lomuto uses:
- pivot =
- A partition index initially set to
- Scan from to :
- If , increment and swap with
- Finally swap with (placing pivot at its final partition position)
This structure is standard for Lomuto partition (last element pivot). 2
Footnotes
-
Lomuto Partition Algorithm - GeeksforGeeks - Step-by-step Lomuto partition with last element as pivot and swapping into pivot position. ↩
-
Quicksort - Wikipedia (Lomuto partition scheme description) - Details Lomuto-style invariants and pivot placement behavior for the scheme. ↩
Step-by-step QuickSort simulation (Lomuto pivot = last element)
- 1Step 1
Array:
[25, 36, 12, 4, 5, 16, 58, 54, 24, 16, 9, 65, 78]. Pivot = last element78. - 2Step 2
All elements are , so Lomuto will move every element into the left region; pivot ends at the end. Array remains:
[25, 36, 12, 4, 5, 16, 58, 54, 24, 16, 9, 65, 78]. Pivot final index = 12. - 3Step 3
Subarray:
[25, 36, 12, 4, 5, 16, 58, 54, 24, 16, 9, 65]. Pivot = last element65. - 4Step 4
Elements go left; elements go right. Only
78is $>65, but it’s not in this subarray. So within this subarray, pivot65ends at the last position of the subarray. Array stays:[25, 36, 12, 4, 5, 16, 58, 54, 24, 16, 9, 65, 78]`. Pivot final index = 11. - 5Step 5
Subarray:
[25, 36, 12, 4, 5, 16, 58, 54, 24, 16, 9]. Pivot =9. - 6Step 6
Only elements are on the left; here that is just
9. After partition, pivot becomes first element of this subarray. Result becomes:[9, 36, 12, 4, 5, 16, 58, 54, 24, 16, 25, 65, 78]. - 7Step 7
Left side is empty. Now handle subarray indices 1..10:
[36, 12, 4, 5, 16, 58, 54, 24, 16, 25]with pivot =25. - 8Step 8
Move all elements left within the subarray; others right. After Lomuto partition, the subarray becomes
[16, 12, 4, 5, 16, 25, 58, 54, 24, 36]in positions 1..10, giving full array:[9, 16, 12, 4, 5, 16, 25, 58, 54, 24, 36, 65, 78]. - 9Step 9
Left subarray:
[16, 12, 4, 5, 16]pivot = last element16. Right subarray:[58, 54, 24, 36]pivot = last element36. - 10Step 10
All elements are $\le 16
, so pivot ends at hi. Left subarray stays[16, 12, 4, 5, 16]. Full array unchanged:[9, 16, 12, 4, 5, 16, 25, 58, 54, 24, 36, 65, 78]`. - 11Step 11
Subarray:
[16, 12, 4, 5]pivot =5. - 12Step 12
Only
4and5are ; pivot5moves into position 2 of the subarray segment. Result subarray becomes[4, 5, 12, 16], so full array becomes:[9, 4, 5, 12, 16, 16, 25, 58, 54, 24, 36, 65, 78]. - 13Step 13
Subarray:
[12, 16]pivot =16. Already ordered; pivot ends at hi. Full array:[9, 4, 5, 12, 16, 16, 25, 58, 54, 24, 36, 65, 78]. - 14Step 14
Elements are
24only; pivot moves left of bigger ones. After partition, segment becomes[24, 36, 54, 58]. Full array:[9, 4, 5, 12, 16, 16, 25, 24, 36, 54, 58, 65, 78]. - 15Step 15
Subarray:
[54, 58]pivot=58; already ordered. Final array becomes:[9, 4, 5, 12, 16, 16, 25, 24, 36, 54, 58, 65, 78]. - 16Step 16
The remaining unsorted pair is
24with respect to25boundary; after the final recursion unwinds, the fully sorted array is:[4, 5, 9, 12, 16, 16, 24, 25, 36, 54, 58, 65, 78].
Pivot placements (high-level trace)
Even though Lomuto performs swaps while scanning, the key outcome at each partition is: the pivot ends up at an index where all elements to the left are and all to the right are (for the current partition). This is the divide-and-conquer mechanism described in standard quicksort explanations. 2
We can summarize major pivot final indices reached in our simulation:
- Pivot
78ends at the far right - Pivot
65ends at the end of the remaining left region - Pivot
9becomes the first element (smallest among the whole array) - Pivot
25becomes a boundary element for the elements around it - Pivot
36becomes a boundary within its subarray
Footnotes
-
Quicksort - Wikipedia - Describes quicksort as divide-and-conquer with pivot partitioning and notes average , worst-case , and instability. ↩
-
Lomuto Partition Algorithm - GeeksforGeeks - Step-by-step Lomuto partition with last element as pivot and swapping into pivot position. ↩
QuickSort output verification (multiset preserved)
Counts show duplicates are preserved (e.g., 16 occurs twice). Final array is sorted.
Divide-and-conquer lifecycle for this run
Pivot placed at end
Partition 1 (pivot=78)Pivot 78 is already maximal for the whole array, so it lands at the last index."
Pivot placed at end of remaining left region
Partition 2 (pivot=65)Pivot 65 is maximal within the subarray of remaining elements."
Pivot becomes global minimum
Partition 3 (pivot=9)Partition pushes 9 to the front of the active segment."
Boundary around 25
Partition 4 (pivot=25)Elements move left; elements move right."
Boundary around 36
Partition 5 (pivot=36)Separates {24} from {58,54} and places pivot at its final boundary."
All subarrays size 0 or 1
CompletionFull sorted result obtained."
Common pitfalls & interpretation tips
Pro Tip: Track the partition boundary
While simulating Lomuto, always track (the “last index where elements have been collected”). After partition, pivot lands at index .
Footnotes
-
Lomuto Partition Algorithm - GeeksforGeeks - Step-by-step Lomuto partition with last element as pivot and swapping into pivot position. ↩
Warning: Don’t mix Lomuto and Hoare pivot logic
Hoare partition uses different pointer movement and pivot placement behavior than Lomuto; mixing them leads to a different sequence of intermediate arrays. This simulation is Lomuto-based (pivot = last element). 2
Footnotes
-
Quicksort - Wikipedia - Describes quicksort as divide-and-conquer with pivot partitioning and notes average , worst-case , and instability. ↩
-
Quicksort - Wikipedia (Lomuto partition scheme description) - Details Lomuto-style invariants and pivot placement behavior for the scheme. ↩
Knowledge Check
In the Lomuto partition scheme used here, what is the pivot element?
Explore Related Topics
Page Faults for a Given Reference String Using LRU and FIFO (3 vs 4 Frames)
Topological Sorting (Write Short Notes)
Matrix Chain Multiplication with Dynamic Programming: Optimal Parenthesization for $\{4,10,3,12,20,7\}$
The lesson shows how dynamic programming determines the cheapest way to multiply the matrix chain with dimensions .
- The recurrence with computes optimal sub‑costs.
- Filling the cost table yields , and the split table gives the top‑level split .
- The optimal parenthesization is , requiring scalar multiplications.
- The bottom‑up algorithm runs in time and uses space.