Quicksort: Difference between revisions
(7 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
=Internal= | =Internal= | ||
* [[ | * [[Recursive_Algorithms#Divide_and_Conquer|Divide and Conquer Algorithms]] | ||
* [[Sorting_Algorithms#Sorting_Algorithms|Sorting Algorithms]] | * [[Sorting_Algorithms#Sorting_Algorithms|Sorting Algorithms]] | ||
* [[The Partition Subroutine]] | * [[The Partition Subroutine]] | ||
=Overview= | =Overview= | ||
Line 17: | Line 18: | ||
=Algorithm= | =Algorithm= | ||
The key idea of Quicksort is to partition an array around a pivot. The pivot is chosen randomly and it can be formally shown that randomly choosing a pivot at each step of the algorithm produces an O(n lg n) time complexity on average. | The key idea of Quicksort is to partition an array around a pivot. The pivot is chosen randomly and it can be formally shown that randomly choosing a pivot at each step of the algorithm produces an O(n lg n) time complexity on average. Partitioning an array is discussed here: [[The_Partition_Subroutine#Overview|The Partition Subroutine]]. | ||
After partitioning, we'll end up with three distinct sections of the array: the subarray where all elements are smaller or equal than the pivot, the pivot and the subarray where all elements are bigger than the pivot. | |||
The | The partitioning is the divide phase of the [[Algorithms#Divide_and_Conquer|divide and conquer]] algorithm. | ||
The next step is to "conquer": call quicksort recursively on the first and the last section of the array. The pivot is already in the correct position and we will leave it there. | |||
The last step, "combine", does not do anything. | |||
==Pseudocode== | |||
<font size=-1> | |||
Quicksort(array A, length n) | |||
if n == 1, return | |||
p = ChoosePivot(A, n) | |||
partition A around p | |||
Quicksort(first part of array A) | |||
Quicksort(second part of array A) | |||
</font> | |||
</ | |||
=Time Complexity Analysis= | =Time Complexity Analysis= | ||
QuickSort does not subdivide the problem in equal subproblems at one level, so the [[Master_Method#Overview|master theorem]] does not apply in its current form. | QuickSort does not subdivide the problem in equal subproblems at one level, so the [[Master_Method#Overview|master theorem]] does not apply in its current form. | ||
A discussion of the time complexity is available here: | |||
* https://www.coursera.org/learn/algorithms-divide-conquer/lecture/5Tuvu/analysis-i-a-decomposition-principle | * https://www.coursera.org/learn/algorithms-divide-conquer/lecture/5Tuvu/analysis-i-a-decomposition-principle | ||
* https://www.coursera.org/learn/algorithms-divide-conquer/lecture/sIY1s/analysis-ii-the-key-insight | * https://www.coursera.org/learn/algorithms-divide-conquer/lecture/sIY1s/analysis-ii-the-key-insight | ||
* https://www.coursera.org/learn/algorithms-divide-conquer/lecture/aqD1O/analysis-iii-final-calculations | * https://www.coursera.org/learn/algorithms-divide-conquer/lecture/aqD1O/analysis-iii-final-calculations | ||
</font> | |||
<font color=darkgray>[[CLRS]] pages 174, 180.</font> | |||
=Quicksort and Selection Problem= | =Quicksort and Selection Problem= | ||
The randomized Quicksort algorithm is somewhat similar to the one used by the generic [[Selection Problem|selection problem]]. | The randomized Quicksort algorithm is somewhat similar to the one used by the generic [[Selection Problem|selection problem]]. | ||
=Example= | |||
{{External|[https://github.com/ovidiuf/playground/blob/master/data-structures-and-algorithms/quicksort/src/main/java/playground/dsa/quicksort/Quicksort.java Playground Quicksort]}} |
Latest revision as of 19:11, 9 November 2021
Internal
Overview
Quicksort is an in-place sorting divide-and-conquer algorithm. Being an in-place sorting algorithm is considered preferable to merge sort, which has to allocate extra memory.
Worst-case time | Θ(n2) |
Expected running time | Θ(n lg n) |
Best-case time | Θ(n lg n) |
Algorithm
The key idea of Quicksort is to partition an array around a pivot. The pivot is chosen randomly and it can be formally shown that randomly choosing a pivot at each step of the algorithm produces an O(n lg n) time complexity on average. Partitioning an array is discussed here: The Partition Subroutine.
After partitioning, we'll end up with three distinct sections of the array: the subarray where all elements are smaller or equal than the pivot, the pivot and the subarray where all elements are bigger than the pivot.
The partitioning is the divide phase of the divide and conquer algorithm.
The next step is to "conquer": call quicksort recursively on the first and the last section of the array. The pivot is already in the correct position and we will leave it there.
The last step, "combine", does not do anything.
Pseudocode
Quicksort(array A, length n) if n == 1, return p = ChoosePivot(A, n) partition A around p Quicksort(first part of array A) Quicksort(second part of array A)
Time Complexity Analysis
QuickSort does not subdivide the problem in equal subproblems at one level, so the master theorem does not apply in its current form.
A discussion of the time complexity is available here:
- https://www.coursera.org/learn/algorithms-divide-conquer/lecture/5Tuvu/analysis-i-a-decomposition-principle
- https://www.coursera.org/learn/algorithms-divide-conquer/lecture/sIY1s/analysis-ii-the-key-insight
- https://www.coursera.org/learn/algorithms-divide-conquer/lecture/aqD1O/analysis-iii-final-calculations
CLRS pages 174, 180.
Quicksort and Selection Problem
The randomized Quicksort algorithm is somewhat similar to the one used by the generic selection problem.