quicksort algorithm stability
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Quicksort is one of the most famous sorting algorithms, known for its efficiency and simplicity. However, an interesting aspect of quicksort is its inherent instability when sorting data. This article delves into the concept of sorting stability, examines why quicksort is traditionally unstable, and explores potential methods to implement a stable version of quicksort.
Understanding Sorting Stability
Before addressing quicksort's stability, it's essential to define what "stability" means in the context of sorting algorithms. A sorting algorithm is considered stable if it preserves the relative order of records with equal keys (values). In other words, if two records and have equal values and appears before in the input, should also appear before in the output.
Examples of Stable and Unstable Sorting
To illustrate sorting stability, consider an array of tuples where each tuple consists of a key-value pair. Let's sort an array based on the key:
- Unsorted array:
[(4, 'A'), (2, 'B'), (2, 'A'), (3, 'D'), (4, 'C')] - Stable sort result:
[(2, 'B'), (2, 'A'), (3, 'D'), (4, 'A'), (4, 'C')] - Unstable sort result:
[(2, 'A'), (2, 'B'), (3, 'D'), (4, 'C'), (4, 'A')]
In a stable sort, (2, 'B')
remains before (2, 'A')
, preserving their original order. In contrast, an unstable sort may change this relative order.
Quicksort's Instability
Quicksort is a comparison sort, picking a "pivot" element and partitioning the remaining elements into two sub-arrays: elements less than the pivot and elements greater than the pivot. This process is recursively applied to the sub-arrays.
The fundamental reason for quicksort's instability is its reorganization of elements during partitioning. Elements that are equal to the pivot can end up in different parts of the array without preserving their initial order, particularly when using common partitioning schemes (like Lomuto or Hoare).
Example of Quicksort's Instability
Consider sorting the following array using quicksort:
- Unsorted array:
[(2, 'B'), (2, 'A'), (2, 'C')]
Using quicksort with a simple partitioning scheme could result in:
- Unstable sort result:
[(2, 'A'), (2, 'B'), (2, 'C')]
Here, the original order among equal elements is not preserved, illustrating quicksort's typical instability.
Modifying Quicksort for Stability
While quicksort is paradigmatically unstable, modifications can be made to make it stable, though at the cost of increased complexity and potential performance trade-offs.
Techniques for Stable Quicksort
- Using Stable Partitioning: Implementing a stable partitioning algorithm ensures that equal elements preserve their order relative to the pivot.
- Tagging Elements: Alter each element with its initial index during comparisons and partitions to maintain stability.
By using stable partitioning or tagging elements, one can achieve a stable quicksort. However, these techniques often complicate the algorithm and may result in performance losses compared to typical implementations.
Comparison with Other Algorithms
To understand quicksort's stability further, it's useful to compare it with other sorting algorithms:
| Algorithm | Stability | Time Complexity | Space Complexity |
| Quicksort | No | ||
| Merge Sort | Yes | ||
| Bubble Sort | Yes | ||
| Insertion Sort | Yes | ||
| Heap Sort | No |
While quicksort is highly efficient, merge sort provides a stable option with similar time complexity but a larger space footprint.
Conclusion
Quicksort's popularity stems from its excellent average-case performance and ease of implementation. However, its typical form lacks stability, which can be crucial in certain applications. Understanding and potentially transforming quicksort for stable sorting can be beneficial, though one must weigh these adjustments' costs and benefits.
In applications where stability is a priority, other sorting algorithms like merge sort might be a more appropriate choice unless specific adaptations of quicksort are made. Nonetheless, quicksort remains an invaluable tool in a programmer's toolkit due to its speed and adaptability.
Related reading
- Quicksort Choosing the pivot
- Quicksort complexity when all the elements are same?
- Quicksort Iterative or Recursive
- Quicksort pivot position after one partition
- Quicksort superiority over Heap Sort
- R How to split a data frame into training, validation, and test sets?
- Quicksort slower than Mergesort?
- Quicksort vs heapsort

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.