Hoare's partition scheme ‐ intuition
Basic implementation:
template<typename T>
int partition(vector<T>& xs, int start, int end) {
T pivot = xs[start]; // (a)
int left = start - 1;
int right = end + 1;
while(true) {
do {++left;} while(xs[left] < pivot); // (b)
do {--right;} while(xs[right] > pivot); // (c)
if(left >= right) return right; // (d)
swap(xs[left], xs[right]); // (e)
}
}
Notes:
- In (a) it is important to select
leftas pivot, so in (b) and © we don't need boundary checks - pivot naturally guards boundaries.- after the first
whileiteration, (e) ensures that pivot is to the right ofleftand somex < pivotis to the left ofright.
- after the first
- (d) returns
right, and notleft, becauseleftwas incrementing and stopped wherexs[left] >= pivot.- If
xs[left] == pivot, thenrightdecrementing stopped atxs[right] == pivotandright == left, so everything beforerightis<= pivot. - If
xs[left] > pivot, thenrightdecrementing stopped atxs[right] < pivotandright == left - 1, so everything beforerightis<= pivotagain. - In any case every element in
xs[start..right]inclusive is<= pivotand every element inxs[right+1..end]inclusive is>= pivot, but pivot duplicates can be on both sides.
- If