How to implement a commonly used sort function with C++?
This sort function:
- Can be used for any comparable type.
- Can be used for C-style array or C++ containers (like vector or list)
- Can be used for the containers with different kinds of iterators, such as RandomAccessIterator, ForwardIterator, BidirectionIterator, etc.
- Users can define their own comparing function / factor / lambda function
Here is an example with C++11. It works well with my g++4.6 compiler.
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <functional>
using namespace std;
template<typename RandomAccessor>
struct myiter_traits {
typedef typename RandomAccessor::value_type value_type;
};
template<typename T>
struct myiter_traits<T*> {
typedef T value_type;
};
template<typename RandomAccessor>
RandomAccessor mypartition(
const RandomAccessor& head,
const RandomAccessor& tail,
function<bool(
typename myiter_traits<RandomAccessor>::value_type va,
typename myiter_traits<RandomAccessor>::value_type vb)> cmp) {
RandomAccessor pivot = head;
RandomAccessor l = head;
RandomAccessor r = tail - 1;
int ptr = 0;
while (l <= r) {
while (l <= r) {
bool lt = cmp(*l, *pivot);
bool gt = cmp(*pivot, *l);
bool eq = !lt && !gt;
if (lt || (eq && ptr == 0)) {
l++;
ptr ^= (eq? 1: 0);
} else {
break;
}
}
while (l <= r) {
bool lt = cmp(*r, *pivot);
bool gt = cmp(*pivot, *r);
bool eq = !lt && !gt;
if (gt || (eq && ptr == 1)) {
r--;
ptr ^= (eq? 1: 0);
} else {
break;
}
}
if (l <= r) {
swap(*l, *r);
l++;
r--;
}
}
swap(*pivot, *r);
return r;
}
template<typename RandomAccessor>
void mysortWithRandomAccessor(
const RandomAccessor& head,
const RandomAccessor& tail,
function<bool(
typename myiter_traits<RandomAccessor>::value_type va,
typename myiter_traits<RandomAccessor>::value_type vb)> cmp
) {
if (tail - head <= 1) {
return;
}
const RandomAccessor pivot = mypartition(head, tail, cmp);
mysortWithRandomAccessor(head, pivot, cmp);
mysortWithRandomAccessor(pivot + 1, tail, cmp);
}
int main() {
function<bool(int, int)> myless = [](int a, int b)->bool { return a < b; };
function<bool(int, int)> mygreater = [](int a, int b)->bool { return a > b; };
vector<int> vec({2, 1, 3, 0, 4, 1999});
mysortWithRandomAccessor(vec.begin(), vec.end(), myless);
for (const auto& i: vec) {
printf("%d ", i);
}
puts("");
int array[] = {99, 19, 9999};
mysortWithRandomAccessor(array + 0, array + 3, mygreater);
for (int i = 0; i < 3; i++) {
printf("%d ", array[i]);
}
puts("");
return 0;
}
Aucun commentaire:
Enregistrer un commentaire