A Clean Version of Quick Sort
2018-08-07
The core idea of quick sort is choosing a pivot first, then moving those smaller than pivot to its left part and those larger than pivot to its right (partition). Each time we put the pivot at the correct position, so we only need to repeat this procedure to pivot’s left part and right part. This is divide and conquer
, which breaks up a larger problem into smaller ones.
My quick sort code before is very ugly and complex, because there are two while loops inside a while loop ! What’s more, I have to think it over and over again each time I use it, since I could’t memorize it. So I decided to make a cleaner version of it. Here is my thinking sharing with you.
Pseudo code for quick sort
|
|
Let me explain it:
- If there is only 1 element to sort, nothing need to be done, just return the original arr.
- If ther are more than 1 elements to sort, we need to repeat the procedure below:
Choose an element as pivot.Pivot
is the element which split the to sort array into 3 parts. One is the left part: elements in this part are all < pivot; one is the right part: elements in this part are all >= pivot; the middle part only contains 1 element — the pivot.
We can assure that, the pivot is at its correct position after such a procedure.
Now the left part and right part are not sorted yet, so we quick_sort(left part) and right part respectively.
How to write partition ?
For me, the most confusing part of the above algorithm is the partition. Recursion is easy to understand. My old version partition part looks like:
So how do we make it easier to understand?
Let’s illustrate partition procedure through an example:
We can find out 4 key points from the above procedure:
- All swaps only happen between low and high. And pivot must be one of low and high. So swap makes the pivot change its position (Either
from low to high
orfrom high to low
).
Note: To remember where is pivot now, I used a variable namedpivot
to record whether it is at low or high. Note thatpivot
only has two states: {“low”, “high”}, and swap() will trigger it to change state. - When should we make a swap?The answer is:
when the low and high are unordered(or in a reversed order)
. - So what if low and high are ordered? The answer is:
just move the non-pivot one step forward (low: -->, high: <--)
. - When to stop? The answer is:
when the low and high meet together (low == high)
.
My clean version parition is shown below:
Complete Code
|
|
|
|
Note: this version’s quick can only make sure all smaller than pivot nums to its left and all larger nums to its right. It can’t make sure that all nums equal to pivot will lie in one side of pivot.