3-Way Qucik Sort
2018-11-10
In my last blog, a clean version of quick sort
was introduced.
Time Complexity of Quick Sort
Quick sort’s average
time complexity is $O(nlogn)$, worst
time complexity is $O(n^2)$.
Average case: A list of random numbers. After each partition the array was splited into two subarrays which have similar lengths. Each partition costs $O(n)$ and we only need $logn$ such partitions. So the time complexity is $O(nlogn)$.
Worst case 1: A sorted list. Each partition can split the list into two subarrays: whose lengths varys a lot(e.g. len_part1 = 1, len_part2 = n - 2). So we need nearly n such partitions. So the time complexity is $O(n^2)$.
Under the worst cases, the quick sort algorithm become not that quick. One solution is choosing a pivot randomly instead of always choosing the first or last element as pivot.
Worst case 2: A list which contains many duplicates. My clean version of quick sort will move all nums which is smaller than pivot to its left and all nums which is larger than pivot to its right part. There is an example for illustration.
|
|
In this example, there are many 3s. So that each partition will not always generate two similar lengths subarrays. Which may also causes trouble like worst case 1.
This blog will introduce a 3-way partition to solve improve worst case 2. The main idea is to split array into 3 parts: left part consists of nums < pivot, middle part consists of nums == pivot and right part consists of nums > pivot.
Dutch National Flag Problem
The 3-way partition is actually the same problem with Dutch National Flag Problem, This problem can be described as: given n intergers which are all in 0, 1, or 2. Sort them so that all 0s occur firstly, 1s occur secondly, and 2s occur lastly.
Note: If you want to practice, Leetcode link is here. An simpler version of this problem is Move Zeros, which contains only 2 colors.
|
|
If we move all 0s ahead, all 2s behind, then all 1s will automatically at mid. So the problem is solved.
Suppose we have two pointers: low and high, low points to current position that we can safely place a 0, high points to current position that we can safely place an 2. For each num, if it’s 0, we swap it with arr[low]; if it is 2, we swap it with arr[high]; if it is 1, nothing to do, we just move to the next num.
Below is the c++ code for this Dutch National Flag problem.
|
|
3-Way Quick Sort
Similar to Dutch National Flag problem, the 3-way partition takes nums < piovt as 0s, nums > pivot as 2s, and nums == pivot as 1s. Below is the quick sort using 3-way partition.
|
|