typedef vector<int> Container;
void printVec(const Container& data)
{
for(int i : data)
printf("%d ", i);
printf("
");
}
void checkSort(function<Container(Container)> sortFunc)
{
printVec(sortFunc(Container{}));
printVec(sortFunc(Container{0}));
printVec(sortFunc(Container{-1, 0}));
printVec(sortFunc(Container{12, -3, 23, -3, 23}));
}
Container BubbleSort(Container data)
{
const int size = data.size ();
for(int i= 0; i != size; ++i)
for(int j = 0; j != size - 1 - i; ++j)
if(data[j] > data[j + 1])
swap(data[j], data[j + 1]);
return data;
}
Container selectSort(Container data)
{
for(auto it = data.begin (); it != data.end (); ++it)
swap(*it, *min_element(it, data.end ()));
return data;
}
pair<int, int> partition(Container& data, int left, int right)
{
assert(left <= right);
const int pivot = data[right];
int lowerBound = left;
int pivotBound = right;
for(int i = left; i != pivotBound;){
if(data[i] < pivot)
swap(data[i++], data[lowerBound++]);
else if(data[i] == pivot)
swap(data[i], data[--pivotBound]);
else
++i;
}
// Now lowerBound to pivotBound is higher section,
// and pivot to right is pivots section.
int offset = min(pivotBound - lowerBound, right - pivotBound + 1);
for(int i = 0; i != offset; ++i){
swap(data[lowerBound + i], data[right - i]);
}
// return lower's tail and higher's head.
return {lowerBound, right - pivotBound + lowerBound};
}
void quickSortIt(Container& data, int left, int right)
{
if(left < right){
auto pivotRange = partition (data, left, right);
quickSortIt (data, left, pivotRange.first - 1);
quickSortIt (data, pivotRange.second + 1, right);
}
}
Container quickSort(Container data)
{
if(data.empty())
return data;
quickSortIt(data, 0, data.size () - 1);
return data;
}
Container quickSortII(Container data)
{
if(data.empty())
return data;
auto partition = [&](int left, int right)
{
const int pivot = data[right];
int lowerBound = left;
int pivotsBound = right;
for(int i = 0; i != pivotsBound;){
if(data[i] < pivot)
swap(data[i++], data[lowerBound++]);
else if(data[i] == pivot)
swap(data[i], data[--pivotsBound]);
else
++i;
}
const int offset = min(pivotsBound - lowerBound, right - pivotsBound + 1);
for(int i = 0; i != offset; ++i){
swap(data[lowerBound + i], data[right - i]);
}
return make_pair(lowerBound, right - pivotsBound + lowerBound);
};
function<void(int, int)> quickSortIt;
quickSortIt = [&](int left, int right)
{
if(left < right){
auto range = partition(left, right);
quickSortIt(left, range.first - 1);
quickSortIt(range.second + 1, right);
}
};
quickSortIt(0, data.size() - 1);
return data;
}