You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: book/chapters/quick-sort.adoc
+39-12
Original file line number
Diff line number
Diff line change
@@ -1,21 +1,21 @@
1
1
= Quicksort
2
2
(((Sorting, QuickSort)))
3
3
(((QuickSort)))
4
-
Quicksort is an efficient recursive sorting algorithm that uses <<Divide and Conquer, divide and conquer>> paradigm to sort faster. It can be implemented in-place so it doesn't require additonal memory.
4
+
Quicksort is an efficient recursive sorting algorithm that uses <<Divide and Conquer, divide and conquer>> paradigm to sort faster. It can be implemented in-place, so it doesn't require additonal memory.
5
5
6
6
indexterm:[Divide and Conquer]
7
-
In practice quicksort outperforms efficient sorting algorithms like <<Merge Sort>>. And, of course, It also outperforms simple sorting algorithms like <<Selection Sort>>, <<Insertion Sort>> and <<Bubble Sort>>.
7
+
In practice, quicksort outperforms other sorting algorithms like <<Merge Sort>>. And, of course, It also outperforms simple sorting algorithms like <<Selection Sort>>, <<Insertion Sort>> and <<Bubble Sort>>.
8
8
9
-
Quicksort basically picks a "pivot" element (preferably random) and move all the elements that are smaller than the pivot to the right and the ones that are bigger to the left. It does this recursively until all the array is sorted.
9
+
Quicksort picks a "pivot" element (preferably random) and move all the parts that are smaller than the pivot to the right and the ones that are bigger to the left. It does this recursively until all the array is sorted.
10
10
11
11
== Quicksort Implementation
12
12
13
13
Quicksort implementation uses the divide-and-conquer in the following way:
14
14
15
15
.Quicksort Algorithm
16
-
. Pick a "pivot" element (at random)
17
-
. Move everything that is lower than the pivot to the left and everything that is bigger than the pivot to the right.
18
-
. Recursively repeat step 1 and 2, the sub-arrays on the left and on the right WITHOUT including the pivot.
16
+
. Pick a "pivot" element (at random).
17
+
. Move everything lower than the pivot to the left and everything more significant than the pivot to the right.
18
+
. Recursively repeat step #1 and #2 in the sub-arrays on the left and on the right WITHOUT including the pivot.
<2> This is the place holder for the final pivot index. We start in low and as we move all the lower elements to the left we will get the final place where the pivot should be.
41
-
<3> Move one element at a time comparing it to the pivot value.
42
-
<4> If the current element value is less than the pivot, then increment pivot index (pivot should be place after all the lower values). We also swap the value before incrementing because current element that is lower than the pivot to be at its left side.
39
+
<1> Take the leftmost element as the pivot.
40
+
<2> `pivotFinalIndex` is the placeholder for the final position where the pivot will be placed when the array is sorted.
41
+
<3> Check all values other than the pivot to see if any value is smaller than the pivot.
42
+
<4> If the `current` element's value is less than the pivot, then increment `pivotFinalIndex` to make room on the left side.
43
+
<5> We also swap the smaller element to the left side since it's smaller than the pivot.
44
+
<6> Finally, we move the pivot to its final position. Everything to the left is smaller than the pivot and everything to the right is bigger.
43
45
44
-
Merge sort has a _O(n log n)_ running time. For more details about the how to extract the runtime go to <<Linearithmic>>.
46
+
*What would happen if use Quicksort for an array in reverse order?*
47
+
48
+
E.g. `[10, 7, 5, 4, 2, 1]`, if we always choose the first element as the pivot, we would have to swap everything to the left of `10`.
49
+
50
+
So in the first partition we would have `[7, 5, 4, 2, 1, 10]`.
51
+
Then, we take `7` would be the next pivot and we have to swap everything to the left.
52
+
This is the worst-case for this quicksort since it will perform O(n^2^) work.
53
+
If instead of partitioning by the first we do it by the middle element (or even better at random) we would have better peformance. That's why we usually shuffle the array to avoid edge cases.
With the optimization, Quicksort has a _O(n log n)_ running time. Similar to the merge sort we divide the array into halves each time. For more details about the how to extract the runtime go to <<Linearithmic>>.
0 commit comments