Quicksort with Python
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
Quicksort is a highly efficient sorting algorithm and is one of the most widely used algorithms for sorting data. It was developed by Tony Hoare in 1960 and is an example of the divide-and-conquer algorithmic paradigm. Quicksort is popular due to its simplicity and its average-case performance comparison.
In this article, we'll delve deep into the mechanics of the Quicksort algorithm, demonstrate how you can implement it in Python, and compare it with other sorting techniques.
Understanding the Algorithm
Quicksort works by selecting a 'pivot' element from the array and partitioning the other elements into two sub-arrays: those less than the pivot and those greater than the pivot. It then recursively sorts the sub-arrays.
Steps of the Algorithm
- Choose a Pivot: A central element of the data array is chosen as the pivot.
- Partitioning: Rearrange the array so that all elements with values less than the pivot come before the pivot, while all elements with values greater than the pivot come after it. After this, the pivot is in its final position.
- Recursively Apply the above steps to the sub-array of elements with smaller values and the sub-array of elements with greater values.
Choosing a Pivot
Selecting the correct pivot is crucial for optimal performance. Common strategies include:
- First Element: Simple and efficient for pre-sorted arrays.
- Last Element: Similarly simple but not as efficient for sorted arrays in reverse.
- Random Element: An unbiased approach that helps in reducing the chances of encountering worst-case performance.
- Median-of-Three: Choose the median of the first, middle, and last elements.
Example Python Implementation
Here’s how you can implement the Quicksort algorithm in Python:
Technical Explanation
- The function
quicksortsorts an array. If the array has one or zero elements, it is already sorted. - The pivot is chosen as the middle element.
- The list is partitioned into three lists:
left,middle, andright. - The algorithm is recursively applied to the left and right sub-lists.
- The results are concatenated together to produce the sorted list.
Time Complexity
| Time Complexity | Best | Average | Worst |
| Quicksort |
- Best and Average Case: – occurs when the pivot divides the array into two nearly equal halves.
- Worst Case: – occurs when the smallest or largest element is always picked as the pivot resulting in highly unbalanced splits. This can particularly happen when the input is already sorted.
Key Characteristics
- In-Place Sorting: Quicksort rearranges elements within the input data structure. However, the simple Python implementation above is not in-place due to list comprehensions.
- Recursive: Utilizes the call stack for recursive calls, which can lead to stack overflow in languages or environments with limited stack size.
- Unstable: Does not guarantee the initial order of equal elements.
Enhancements and Optimizations
Tail Recursion Elimination
To optimize recursive calls and prevent stack overflow, especially for large datasets, tail recursion elimination or iterative methods can be used.
Three-Way Partitioning
Another optimization is a three-way partitioning technique that handles duplicate keys more efficiently by dividing the array into three parts:
- Elements less than the pivot.
- Elements equal to the pivot.
- Elements greater than the pivot.
Hybrid Approaches
In practice, many languages and libraries employ hybrid algorithms that switch to simpler algorithms like insertion sort when the data size is sufficiently small, as insertion sort provides less overhead for small datasets.
Conclusion
Quicksort is an elegant and efficient algorithm for sorting datasets, balancing its average-case efficiency with the elegance of its design. Although its worst-case performance is sub-optimal, diverse optimizations and hybrid approaches mitigate this, making Quicksort a formidable choice in computational sorting applications.
By understanding its implementation and deepening our knowledge of optimization strategies, Quicksort remains relevant and commandingly effective in modern computing contexts. Whether you are a beginner learning sorting algorithms or an advanced developer optimizing software, mastering Quicksort can significantly enhance your algorithm toolkit.
Related reading
- Quorum vs Consensus vs Vector Clock
- Radial Tree layout algorithm
- Radix sort LSD versus MSD versions
- Radix sort vs Counting sort vs Bucket sort. What's the difference?
- RabbitMQ def callback(ch, method, properties, body)
- RabbitMQ How to send Python dictionary between Python producer and consumer?
- Raft leader election algorithm one vote for term?
- raft state is not determined

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.