Skip to content

Instantly share code, notes, and snippets.

@sguzman
Created March 24, 2015 02:38
Show Gist options
  • Save sguzman/3e469ba05d4107dd9359 to your computer and use it in GitHub Desktop.
Save sguzman/3e469ba05d4107dd9359 to your computer and use it in GitHub Desktop.
A qsort implementation
#include <iostream>
#include <cstdlib>
#include <vector>
#include "pretty_print.hxx"
using namespace std;
template <typename A>
using conref = const A&;
template <typename A, size_t sz>
using arry = conref<array<A,sz>> const;
template <typename A>
class quicksort final {
public:
template <typename... B>
explicit quicksort(B... b) = delete;
template <typename... B>
void operator=(B... b) = delete;
template <typename B>
operator B(void) = delete;
static vector<A> qsort(vector<A> in) {
if (in.size() == 0) {
return in;
}
auto piv = pivot(in);
vector<A> lessThan, equal, greaterThan;
siphon(in, lessThan, equal, greaterThan, piv);
return addV(qsort(lessThan), equal, qsort(greaterThan));
}
private:
// Attempt at the median of 3
static inline A pivot(conref<vector<A>> vec) {
auto& first = vec.front();
auto& second = vec[vec.size() >> 1];
auto& third = vec[vec.size() - 1];
if (first > second && second > third) {
return second;
} else if (third > first && first > second) {
return first;
} else {
return third;
}
}
static void siphon(conref<vector<A>> main, vector<A>& le, vector<A>& eq, vector<A>& ge, A piv) {
for (auto& ele : main) {
if (ele > piv) {
ge.push_back(ele);
} else if (ele < piv) {
le.push_back(ele);
} else {
eq.push_back(ele);
}
}
}
static vector<A> addV(conref<vector<A>> a, conref<vector<A>> b) {
vector<A> final;
for (auto& c : a) {
final.push_back(c);
}
for (auto& c : b) {
final.push_back(c);
}
return final;
}
template <typename... B>
static vector<A> addV(conref<vector<A>> a, conref<vector<A>> b, B... c) {
return addV(addV(a, b), c...);
}
};
int main() {
vector<int> input{6, 1, 7, 2, 9, 3, 4, 5, 8};
vector<int> actual = quicksort<int>::qsort(input);
vector<int> expected{1, 2, 3, 4, 5, 6, 7, 8, 9};
cout << "Input: " << input << endl;
cout << "Actual: " << actual << endl;
cout << "Expected: " << expected << endl;
return EXIT_SUCCESS;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment